diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5feaf2461..8b1048f65 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,8 @@
- The `alternate_name` is now displayed in the borehole detail header and the map markers.
- From depth and to depth are no longer displayed in groundwater level measurements.
- Updated the layout of the borehole general tab.
+- Removed deduplication check when adding and detaching attachments.
+- When copying a borehole, attachments won't be copied.
### Fixed
diff --git a/src/api/BdmsContextExtensions.cs b/src/api/BdmsContextExtensions.cs
index 783ac425c..f5c17fbcf 100644
--- a/src/api/BdmsContextExtensions.cs
+++ b/src/api/BdmsContextExtensions.cs
@@ -216,7 +216,6 @@ public static void SeedData(this BdmsContext context)
.RuleFor(o => o.UpdatedBy, _ => default!)
.RuleFor(o => o.Updated, _ => default!)
.RuleFor(o => o.Name, f => f.Random.Word())
- .RuleFor(o => o.Hash, f => f.Random.Hash())
.RuleFor(o => o.Type, f => f.Random.Word())
.RuleFor(o => o.Created, f => f.Date.Past().ToUniversalTime().OrNull(f, .05f))
.RuleFor(o => o.NameUuid, f => null);
diff --git a/src/api/BoreholeFileCloudService.cs b/src/api/BoreholeFileCloudService.cs
index 871dc8bcc..5cd5585e9 100644
--- a/src/api/BoreholeFileCloudService.cs
+++ b/src/api/BoreholeFileCloudService.cs
@@ -31,22 +31,10 @@ public BoreholeFileCloudService(BdmsContext context, IConfiguration configuratio
///
/// Uploads a file to the cloud storage and links it to the borehole.
///
- /// The file to upload and link to the .
- /// The to link the uploaded to.
- public async Task UploadFileAndLinkToBorehole(IFormFile file, int boreholeId)
+ /// The file to upload and link to the .
+ /// The to link the uploaded to.
+ public async Task UploadFileAndLinkToBorehole(IFormFile formFile, int boreholeId)
{
- // Generate a hash based on the file content.
- var base64Hash = "";
- using (SHA256 sha256Hash = SHA256.Create())
- {
- using Stream stream = file.OpenReadStream();
- byte[] hashBytes = await sha256Hash.ComputeHashAsync(stream).ConfigureAwait(false);
- base64Hash = Convert.ToBase64String(hashBytes);
- }
-
- // Check any file with the same hash already exists in the database.
- var fileId = context.Files.FirstOrDefault(f => f.Hash == base64Hash)?.Id;
-
// Use transaction to ensure data is only stored to db if the file upload was sucessful. Only create a transaction if there is not already one from the calling method.
using var transaction = context.Database.CurrentTransaction == null ? await context.Database.BeginTransactionAsync().ConfigureAwait(false) : null;
try
@@ -60,28 +48,26 @@ public async Task UploadFileAndLinkToBorehole(IFormFile file, int
if (user == null || subjectId == null) throw new InvalidOperationException($"No user with subject_id <{subjectId}> found.");
- // If file does not exist on storage, upload it and create file in database.
- if (fileId == null)
- {
- var fileExtension = Path.GetExtension(file.FileName);
- var fileNameGuid = $"{Guid.NewGuid()}{fileExtension}";
+ // Register the new file in the boreholes database.
+ var fileExtension = Path.GetExtension(formFile.FileName);
+ var fileNameGuid = $"{Guid.NewGuid()}{fileExtension}";
- var bdmsFile = new Models.File { Name = file.FileName, NameUuid = fileNameGuid, Hash = base64Hash, Type = file.ContentType };
+ var file = new Models.File { Name = formFile.FileName, NameUuid = fileNameGuid, Type = formFile.ContentType };
- await context.Files.AddAsync(bdmsFile).ConfigureAwait(false);
- await context.UpdateChangeInformationAndSaveChangesAsync(httpContextAccessor.HttpContext!).ConfigureAwait(false);
+ await context.Files.AddAsync(file).ConfigureAwait(false);
+ await context.UpdateChangeInformationAndSaveChangesAsync(httpContextAccessor.HttpContext!).ConfigureAwait(false);
- fileId = bdmsFile.Id;
+ var fileId = file.Id;
- // Upload the file to the cloud storage.
- await UploadObject(file, fileNameGuid).ConfigureAwait(false);
- }
+ // Upload the file to the cloud storage.
+ await UploadObject(formFile, fileNameGuid).ConfigureAwait(false);
// If file is already linked to the borehole, throw an exception.
- if (context.BoreholeFiles.Any(bf => bf.BoreholeId == boreholeId && bf.FileId == fileId)) throw new InvalidOperationException($"File <{file.FileName}> is already attached to borehole with Id <{boreholeId}>.");
+ if (await context.BoreholeFiles.AnyAsync(bf => bf.BoreholeId == boreholeId && bf.FileId == fileId).ConfigureAwait(false))
+ throw new InvalidOperationException($"File <{formFile.FileName}> is already attached to borehole with Id <{boreholeId}>.");
// Link file to the borehole.
- var boreholeFile = new BoreholeFile { FileId = (int)fileId, BoreholeId = boreholeId, UserId = user.Id, Attached = DateTime.UtcNow };
+ var boreholeFile = new BoreholeFile { FileId = fileId, BoreholeId = boreholeId, UserId = user.Id, Attached = DateTime.UtcNow };
var entityEntry = await context.BoreholeFiles.AddAsync(boreholeFile).ConfigureAwait(false);
await context.UpdateChangeInformationAndSaveChangesAsync(httpContextAccessor.HttpContext!).ConfigureAwait(false);
@@ -91,7 +77,7 @@ public async Task UploadFileAndLinkToBorehole(IFormFile file, int
}
catch (Exception ex)
{
- logger.LogError(ex, $"Error attaching file <{file.FileName}> to borehole with Id <{boreholeId}>.");
+ logger.LogError(ex, "Error attaching file <{FileName}> to borehole with Id <{BoreholeId}>.", formFile.FileName, boreholeId);
throw;
}
}
diff --git a/src/api/Controllers/BoreholeController.cs b/src/api/Controllers/BoreholeController.cs
index 135a71cc2..8875ffeb9 100644
--- a/src/api/Controllers/BoreholeController.cs
+++ b/src/api/Controllers/BoreholeController.cs
@@ -296,10 +296,8 @@ await Context.Entry(hydrotest)
}
}
- foreach (var boreholeFile in borehole.BoreholeFiles)
- {
- boreholeFile.BoreholeId = 0;
- }
+ // Do not copy borehole attachments
+ borehole.BoreholeFiles.Clear();
foreach (var boreholeGeometry in borehole.BoreholeGeometry)
{
diff --git a/src/api/Controllers/BoreholeFileController.cs b/src/api/Controllers/BoreholeFileController.cs
index 11aa1200b..6568c36b3 100644
--- a/src/api/Controllers/BoreholeFileController.cs
+++ b/src/api/Controllers/BoreholeFileController.cs
@@ -210,9 +210,9 @@ public async Task DetachFromBorehole([Required, Range(1, int.MaxV
try
{
// Get the file and its borehole files from the database.
- var boreholeFile = await context.BoreholeFiles.Include(f => f.File).FirstOrDefaultAsync(f => f.FileId == boreholeFileId).ConfigureAwait(false);
+ var boreholeFile = await context.BoreholeFiles.Include(f => f.File).SingleOrDefaultAsync(f => f.FileId == boreholeFileId).ConfigureAwait(false);
- if (boreholeFile == null) return NotFound();
+ if (boreholeFile == null) return NotFound($"Borehole file for the provided {nameof(boreholeFileId)} not found.");
var fileId = boreholeFile.File.Id;
@@ -220,11 +220,9 @@ public async Task DetachFromBorehole([Required, Range(1, int.MaxV
context.BoreholeFiles.Remove(boreholeFile);
await context.SaveChangesAsync().ConfigureAwait(false);
- // Get the file and its borehole files from the database.
- var file = await context.Files.Include(f => f.BoreholeFiles).FirstOrDefaultAsync(f => f.Id == fileId).ConfigureAwait(false);
-
- // If the file is not linked to any boreholes, delete it from the cloud storage and the database.
- if (file?.NameUuid != null && file.BoreholeFiles.Count == 0)
+ // Delete the file from the cloud storage and the database.
+ var file = await context.Files.SingleOrDefaultAsync(f => f.Id == fileId).ConfigureAwait(false);
+ if (file?.NameUuid != null)
{
await boreholeFileCloudService.DeleteObject(file.NameUuid).ConfigureAwait(false);
context.Files.Remove(file);
diff --git a/src/api/Migrations/20241122080247_RemoveFileHash.Designer.cs b/src/api/Migrations/20241122080247_RemoveFileHash.Designer.cs
new file mode 100644
index 000000000..588b55ead
--- /dev/null
+++ b/src/api/Migrations/20241122080247_RemoveFileHash.Designer.cs
@@ -0,0 +1,3277 @@
+//
+using System;
+using BDMS;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using NetTopologySuite.Geometries;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace BDMS.Migrations
+{
+ [DbContext(typeof(BdmsContext))]
+ [Migration("20241122080247_RemoveFileHash")]
+ partial class RemoveFileHash
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasDefaultSchema("bdms")
+ .HasAnnotation("ProductVersion", "8.0.0")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "ltree");
+ NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis");
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("BDMS.Models.Backfill", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CasingId")
+ .HasColumnType("integer")
+ .HasColumnName("casing_id");
+
+ b.Property("CompletionId")
+ .HasColumnType("integer")
+ .HasColumnName("completion_id");
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("creation");
+
+ b.Property("CreatedById")
+ .HasColumnType("integer")
+ .HasColumnName("creator");
+
+ b.Property("FromDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("from_depth");
+
+ b.Property("IsOpenBorehole")
+ .HasColumnType("boolean")
+ .HasColumnName("is_open_borehole");
+
+ b.Property("KindId")
+ .HasColumnType("integer")
+ .HasColumnName("kind_id");
+
+ b.Property("MaterialId")
+ .HasColumnType("integer")
+ .HasColumnName("material_id");
+
+ b.Property("Notes")
+ .HasColumnType("text")
+ .HasColumnName("notes");
+
+ b.Property("ToDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("to_depth");
+
+ b.Property("Updated")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("update");
+
+ b.Property("UpdatedById")
+ .HasColumnType("integer")
+ .HasColumnName("updater");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CasingId");
+
+ b.HasIndex("CompletionId");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("KindId");
+
+ b.HasIndex("MaterialId");
+
+ b.HasIndex("UpdatedById");
+
+ b.ToTable("backfill", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.Borehole", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id_bho");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("AlternateName")
+ .HasColumnType("text")
+ .HasColumnName("alternate_name_bho");
+
+ b.Property("Canton")
+ .HasColumnType("text")
+ .HasColumnName("canton_bho");
+
+ b.Property("ChronostratigraphyId")
+ .HasColumnType("integer")
+ .HasColumnName("chronostrat_id_cli");
+
+ b.Property("Country")
+ .HasColumnType("text")
+ .HasColumnName("country_bho");
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_bho");
+
+ b.Property("CreatedById")
+ .HasColumnType("integer")
+ .HasColumnName("created_by_bho");
+
+ b.Property("ElevationPrecisionId")
+ .HasColumnType("integer")
+ .HasColumnName("qt_elevation_id_cli");
+
+ b.Property("ElevationZ")
+ .HasColumnType("double precision")
+ .HasColumnName("elevation_z_bho");
+
+ b.Property("Geometry")
+ .HasColumnType("geometry")
+ .HasColumnName("geom_bho");
+
+ b.Property("HasGroundwater")
+ .HasColumnType("boolean")
+ .HasColumnName("groundwater_bho");
+
+ b.Property("HrsId")
+ .HasColumnType("integer")
+ .HasColumnName("hrs_id_cli");
+
+ b.Property("IsPublic")
+ .HasColumnType("boolean")
+ .HasColumnName("public_bho");
+
+ b.Property("LithologyTopBedrockId")
+ .HasColumnType("integer")
+ .HasColumnName("lithology_top_bedrock_id_cli");
+
+ b.Property("LithostratigraphyId")
+ .HasColumnType("integer")
+ .HasColumnName("lithostrat_id_cli");
+
+ b.Property("LocationPrecisionId")
+ .HasColumnType("integer")
+ .HasColumnName("qt_location_id_cli");
+
+ b.Property("LocationX")
+ .HasColumnType("double precision")
+ .HasColumnName("location_x_bho");
+
+ b.Property("LocationXLV03")
+ .HasColumnType("double precision")
+ .HasColumnName("location_x_lv03_bho");
+
+ b.Property("LocationY")
+ .HasColumnType("double precision")
+ .HasColumnName("location_y_bho");
+
+ b.Property("LocationYLV03")
+ .HasColumnType("double precision")
+ .HasColumnName("location_y_lv03_bho");
+
+ b.Property("Locked")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("locked_bho");
+
+ b.Property("LockedById")
+ .HasColumnType("integer")
+ .HasColumnName("locked_by_bho");
+
+ b.Property("Municipality")
+ .HasColumnType("text")
+ .HasColumnName("municipality_bho");
+
+ b.Property("NationalInterest")
+ .HasColumnType("boolean")
+ .HasColumnName("national_interest");
+
+ b.Property("OriginalName")
+ .HasColumnType("text")
+ .HasColumnName("original_name_bho");
+
+ b.Property("OriginalReferenceSystem")
+ .HasColumnType("integer")
+ .HasColumnName("srs_id_cli");
+
+ b.Property("PrecisionLocationX")
+ .HasColumnType("integer")
+ .HasColumnName("precision_location_x");
+
+ b.Property("PrecisionLocationXLV03")
+ .HasColumnType("integer")
+ .HasColumnName("precision_location_x_lv03");
+
+ b.Property("PrecisionLocationY")
+ .HasColumnType("integer")
+ .HasColumnName("precision_location_y");
+
+ b.Property("PrecisionLocationYLV03")
+ .HasColumnType("integer")
+ .HasColumnName("precision_location_y_lv03");
+
+ b.Property("ProjectName")
+ .HasColumnType("text")
+ .HasColumnName("project_name_bho");
+
+ b.Property("PurposeId")
+ .HasColumnType("integer")
+ .HasColumnName("purpose_id_cli");
+
+ b.Property("QtDepthId")
+ .HasColumnType("integer")
+ .HasColumnName("qt_depth_id_cli");
+
+ b.Property("QtReferenceElevationId")
+ .HasColumnType("integer")
+ .HasColumnName("qt_reference_elevation_id_cli");
+
+ b.Property("ReferenceElevation")
+ .HasColumnType("double precision")
+ .HasColumnName("reference_elevation_bho");
+
+ b.Property("ReferenceElevationTypeId")
+ .HasColumnType("integer")
+ .HasColumnName("reference_elevation_type_id_cli");
+
+ b.Property("Remarks")
+ .HasColumnType("text")
+ .HasColumnName("remarks_bho");
+
+ b.Property("RestrictionId")
+ .HasColumnType("integer")
+ .HasColumnName("restriction_id_cli");
+
+ b.Property("RestrictionUntil")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("restriction_until_bho");
+
+ b.Property("StatusId")
+ .HasColumnType("integer")
+ .HasColumnName("status_id_cli");
+
+ b.Property("TopBedrockFreshMd")
+ .HasColumnType("double precision")
+ .HasColumnName("top_bedrock_fresh_md");
+
+ b.Property("TopBedrockWeatheredMd")
+ .HasColumnType("double precision")
+ .HasColumnName("top_bedrock_weathered_md");
+
+ b.Property("TotalDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("total_depth_bho");
+
+ b.Property("TypeId")
+ .HasColumnType("integer")
+ .HasColumnName("borehole_type_id");
+
+ b.Property("Updated")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("updated_bho");
+
+ b.Property("UpdatedById")
+ .HasColumnType("integer")
+ .HasColumnName("updated_by_bho");
+
+ b.Property("WorkgroupId")
+ .HasColumnType("integer")
+ .HasColumnName("id_wgp_fk");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ChronostratigraphyId");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("ElevationPrecisionId");
+
+ b.HasIndex("HrsId");
+
+ b.HasIndex("LithologyTopBedrockId");
+
+ b.HasIndex("LithostratigraphyId");
+
+ b.HasIndex("LocationPrecisionId");
+
+ b.HasIndex("LockedById");
+
+ b.HasIndex("PurposeId");
+
+ b.HasIndex("QtDepthId");
+
+ b.HasIndex("QtReferenceElevationId");
+
+ b.HasIndex("ReferenceElevationTypeId");
+
+ b.HasIndex("RestrictionId");
+
+ b.HasIndex("StatusId");
+
+ b.HasIndex("TypeId");
+
+ b.HasIndex("UpdatedById");
+
+ b.HasIndex("WorkgroupId");
+
+ b.ToTable("borehole", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.BoreholeCodelist", b =>
+ {
+ b.Property("BoreholeId")
+ .HasColumnType("integer")
+ .HasColumnName("borehole_id");
+
+ b.Property("CodelistId")
+ .HasColumnType("integer")
+ .HasColumnName("identifier_id");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("identifier_value");
+
+ b.HasKey("BoreholeId", "CodelistId");
+
+ b.HasIndex("CodelistId");
+
+ b.ToTable("borehole_identifiers_codelist", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.BoreholeFile", b =>
+ {
+ b.Property("BoreholeId")
+ .HasColumnType("integer")
+ .HasColumnName("id_bho_fk");
+
+ b.Property("FileId")
+ .HasColumnType("integer")
+ .HasColumnName("id_fil_fk");
+
+ b.Property("Attached")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("attached_bfi");
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_bfi");
+
+ b.Property("CreatedById")
+ .HasColumnType("integer")
+ .HasColumnName("created_by_bfi");
+
+ b.Property("Description")
+ .HasColumnType("text")
+ .HasColumnName("description_bfi");
+
+ b.Property("Public")
+ .HasColumnType("boolean")
+ .HasColumnName("public_bfi");
+
+ b.Property("Updated")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("update_bfi");
+
+ b.Property("UpdatedById")
+ .HasColumnType("integer")
+ .HasColumnName("updater_bfi");
+
+ b.Property("UserId")
+ .HasColumnType("integer")
+ .HasColumnName("id_usr_fk");
+
+ b.HasKey("BoreholeId", "FileId");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("FileId");
+
+ b.HasIndex("UpdatedById");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("borehole_files", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.BoreholeGeometryElement", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("BoreholeId")
+ .HasColumnType("integer")
+ .HasColumnName("borehole_id");
+
+ b.Property("DEVI")
+ .HasColumnType("double precision");
+
+ b.Property("HAZI")
+ .HasColumnType("double precision");
+
+ b.Property("MD")
+ .HasColumnType("double precision");
+
+ b.Property("X")
+ .HasColumnType("double precision");
+
+ b.Property("Y")
+ .HasColumnType("double precision");
+
+ b.Property("Z")
+ .HasColumnType("double precision");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BoreholeId");
+
+ b.ToTable("borehole_geometry", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.Casing", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CompletionId")
+ .HasColumnType("integer")
+ .HasColumnName("completion_id");
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("creation");
+
+ b.Property("CreatedById")
+ .HasColumnType("integer")
+ .HasColumnName("creator");
+
+ b.Property("DateFinish")
+ .HasColumnType("date")
+ .HasColumnName("date_finish");
+
+ b.Property("DateStart")
+ .HasColumnType("date")
+ .HasColumnName("date_start");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.Property("Notes")
+ .HasColumnType("text")
+ .HasColumnName("notes");
+
+ b.Property("Updated")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("update");
+
+ b.Property("UpdatedById")
+ .HasColumnType("integer")
+ .HasColumnName("updater");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CompletionId");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("UpdatedById");
+
+ b.ToTable("casing", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.CasingElement", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CasingId")
+ .HasColumnType("integer")
+ .HasColumnName("casing_id");
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("creation");
+
+ b.Property("CreatedById")
+ .HasColumnType("integer")
+ .HasColumnName("creator");
+
+ b.Property("FromDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("from_depth");
+
+ b.Property("InnerDiameter")
+ .HasColumnType("double precision")
+ .HasColumnName("inner_diameter");
+
+ b.Property("KindId")
+ .HasColumnType("integer")
+ .HasColumnName("kind_id");
+
+ b.Property("MaterialId")
+ .HasColumnType("integer")
+ .HasColumnName("material_id");
+
+ b.Property("OuterDiameter")
+ .HasColumnType("double precision")
+ .HasColumnName("outer_diameter");
+
+ b.Property("ToDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("to_depth");
+
+ b.Property("Updated")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("update");
+
+ b.Property("UpdatedById")
+ .HasColumnType("integer")
+ .HasColumnName("updater");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CasingId");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("KindId");
+
+ b.HasIndex("MaterialId");
+
+ b.HasIndex("UpdatedById");
+
+ b.ToTable("casing_element", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.ChronostratigraphyLayer", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id_chr");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("ChronostratigraphyId")
+ .HasColumnType("integer")
+ .HasColumnName("chronostratigraphy_id");
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("creation");
+
+ b.Property("CreatedById")
+ .HasColumnType("integer")
+ .HasColumnName("creator");
+
+ b.Property("FromDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("depth_from");
+
+ b.Property("StratigraphyId")
+ .HasColumnType("integer")
+ .HasColumnName("id_sty_fk");
+
+ b.Property("ToDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("depth_to");
+
+ b.Property("Updated")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("update");
+
+ b.Property("UpdatedById")
+ .HasColumnType("integer")
+ .HasColumnName("updater");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ChronostratigraphyId");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("StratigraphyId");
+
+ b.HasIndex("UpdatedById");
+
+ b.ToTable("chronostratigraphy", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.Codelist", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id_cli");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Code")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("code_cli");
+
+ b.Property("Conf")
+ .HasColumnType("text")
+ .HasColumnName("conf_cli");
+
+ b.Property("De")
+ .HasColumnType("text")
+ .HasColumnName("text_cli_de");
+
+ b.Property("En")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("text_cli_en");
+
+ b.Property("Fr")
+ .HasColumnType("text")
+ .HasColumnName("text_cli_fr");
+
+ b.Property("Geolcode")
+ .HasColumnType("integer")
+ .HasColumnName("geolcode");
+
+ b.Property("IsDefault")
+ .HasColumnType("boolean")
+ .HasColumnName("default_cli");
+
+ b.Property("It")
+ .HasColumnType("text")
+ .HasColumnName("text_cli_it");
+
+ b.Property("Order")
+ .HasColumnType("integer")
+ .HasColumnName("order_cli");
+
+ b.Property("Path")
+ .HasColumnType("ltree")
+ .HasColumnName("path_cli");
+
+ b.Property("Ro")
+ .HasColumnType("text")
+ .HasColumnName("text_cli_ro");
+
+ b.Property("Schema")
+ .HasColumnType("text")
+ .HasColumnName("schema_cli");
+
+ b.HasKey("Id");
+
+ b.ToTable("codelist", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.Completion", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("AbandonDate")
+ .HasColumnType("date")
+ .HasColumnName("abandon_date");
+
+ b.Property("BoreholeId")
+ .HasColumnType("integer")
+ .HasColumnName("borehole_id");
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("creation");
+
+ b.Property("CreatedById")
+ .HasColumnType("integer")
+ .HasColumnName("creator");
+
+ b.Property("IsPrimary")
+ .HasColumnType("boolean")
+ .HasColumnName("is_primary");
+
+ b.Property("KindId")
+ .HasColumnType("integer")
+ .HasColumnName("kind_id");
+
+ b.Property("Name")
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.Property("Notes")
+ .HasColumnType("text")
+ .HasColumnName("notes");
+
+ b.Property("Updated")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("update");
+
+ b.Property("UpdatedById")
+ .HasColumnType("integer")
+ .HasColumnName("updater");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BoreholeId");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("KindId");
+
+ b.HasIndex("UpdatedById");
+
+ b.ToTable("completion", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.Config", b =>
+ {
+ b.Property("Name")
+ .HasColumnType("text")
+ .HasColumnName("name_cfg");
+
+ b.Property("Value")
+ .HasColumnType("text")
+ .HasColumnName("value_cfg");
+
+ b.HasKey("Name");
+
+ b.ToTable("config", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.FaciesDescription", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id_fac");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("creation");
+
+ b.Property("CreatedById")
+ .HasColumnType("integer")
+ .HasColumnName("creator");
+
+ b.Property("Description")
+ .HasColumnType("text")
+ .HasColumnName("description");
+
+ b.Property("DescriptionQualityId")
+ .HasColumnType("integer")
+ .HasColumnName("qt_description_id");
+
+ b.Property("FromDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("depth_from");
+
+ b.Property("StratigraphyId")
+ .HasColumnType("integer")
+ .HasColumnName("id_sty_fk");
+
+ b.Property("ToDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("depth_to");
+
+ b.Property("Updated")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("update");
+
+ b.Property("UpdatedById")
+ .HasColumnType("integer")
+ .HasColumnName("updater");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("DescriptionQualityId");
+
+ b.HasIndex("StratigraphyId");
+
+ b.HasIndex("UpdatedById");
+
+ b.ToTable("facies_description", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.FieldMeasurementResult", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("creation");
+
+ b.Property("CreatedById")
+ .HasColumnType("integer")
+ .HasColumnName("creator");
+
+ b.Property("FieldMeasurementId")
+ .HasColumnType("integer")
+ .HasColumnName("fieldmeasurement_id");
+
+ b.Property("ParameterId")
+ .HasColumnType("integer")
+ .HasColumnName("parameter");
+
+ b.Property("SampleTypeId")
+ .HasColumnType("integer")
+ .HasColumnName("sample_type");
+
+ b.Property("Updated")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("update");
+
+ b.Property("UpdatedById")
+ .HasColumnType("integer")
+ .HasColumnName("updater");
+
+ b.Property("Value")
+ .HasColumnType("double precision")
+ .HasColumnName("value");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("FieldMeasurementId");
+
+ b.HasIndex("ParameterId");
+
+ b.HasIndex("SampleTypeId");
+
+ b.HasIndex("UpdatedById");
+
+ b.ToTable("fieldmeasurement_result", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.File", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id_fil");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("uploaded_fil");
+
+ b.Property("CreatedById")
+ .HasColumnType("integer")
+ .HasColumnName("id_usr_fk");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("name_fil");
+
+ b.Property("NameUuid")
+ .HasColumnType("text")
+ .HasColumnName("name_uuid_fil");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasColumnName("type_fil");
+
+ b.Property("Updated")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("updated_fil");
+
+ b.Property("UpdatedById")
+ .HasColumnType("integer")
+ .HasColumnName("updated_by_fil");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("UpdatedById");
+
+ b.ToTable("files", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.HydrotestEvaluationMethodCode", b =>
+ {
+ b.Property("HydrotestId")
+ .HasColumnType("integer")
+ .HasColumnName("hydrotest_id");
+
+ b.Property("CodelistId")
+ .HasColumnType("integer")
+ .HasColumnName("codelist_id");
+
+ b.HasKey("HydrotestId", "CodelistId");
+
+ b.HasIndex("CodelistId");
+
+ b.ToTable("hydrotest_evaluationmethod_codelist", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.HydrotestFlowDirectionCode", b =>
+ {
+ b.Property("HydrotestId")
+ .HasColumnType("integer")
+ .HasColumnName("hydrotest_id");
+
+ b.Property("CodelistId")
+ .HasColumnType("integer")
+ .HasColumnName("codelist_id");
+
+ b.HasKey("HydrotestId", "CodelistId");
+
+ b.HasIndex("CodelistId");
+
+ b.ToTable("hydrotest_flowdirection_codelist", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.HydrotestKindCode", b =>
+ {
+ b.Property("HydrotestId")
+ .HasColumnType("integer")
+ .HasColumnName("hydrotest_id");
+
+ b.Property("CodelistId")
+ .HasColumnType("integer")
+ .HasColumnName("codelist_id");
+
+ b.HasKey("HydrotestId", "CodelistId");
+
+ b.HasIndex("CodelistId");
+
+ b.ToTable("hydrotest_kind_codelist", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.HydrotestResult", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("creation");
+
+ b.Property("CreatedById")
+ .HasColumnType("integer")
+ .HasColumnName("creator");
+
+ b.Property("HydrotestId")
+ .HasColumnType("integer")
+ .HasColumnName("hydrotest_id");
+
+ b.Property("MaxValue")
+ .HasColumnType("double precision")
+ .HasColumnName("max_value");
+
+ b.Property("MinValue")
+ .HasColumnType("double precision")
+ .HasColumnName("min_value");
+
+ b.Property("ParameterId")
+ .HasColumnType("integer")
+ .HasColumnName("parameter");
+
+ b.Property("Updated")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("update");
+
+ b.Property("UpdatedById")
+ .HasColumnType("integer")
+ .HasColumnName("updater");
+
+ b.Property("Value")
+ .HasColumnType("double precision")
+ .HasColumnName("value");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("HydrotestId");
+
+ b.HasIndex("ParameterId");
+
+ b.HasIndex("UpdatedById");
+
+ b.ToTable("hydrotest_result", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.Instrumentation", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CasingId")
+ .HasColumnType("integer")
+ .HasColumnName("casing_id");
+
+ b.Property("CompletionId")
+ .HasColumnType("integer")
+ .HasColumnName("completion_id");
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("creation");
+
+ b.Property("CreatedById")
+ .HasColumnType("integer")
+ .HasColumnName("creator");
+
+ b.Property("FromDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("from_depth");
+
+ b.Property("IsOpenBorehole")
+ .HasColumnType("boolean")
+ .HasColumnName("is_open_borehole");
+
+ b.Property("KindId")
+ .HasColumnType("integer")
+ .HasColumnName("kind_id");
+
+ b.Property("Name")
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.Property("Notes")
+ .HasColumnType("text")
+ .HasColumnName("notes");
+
+ b.Property("StatusId")
+ .HasColumnType("integer")
+ .HasColumnName("status_id");
+
+ b.Property("ToDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("to_depth");
+
+ b.Property("Updated")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("update");
+
+ b.Property("UpdatedById")
+ .HasColumnType("integer")
+ .HasColumnName("updater");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CasingId");
+
+ b.HasIndex("CompletionId");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("KindId");
+
+ b.HasIndex("StatusId");
+
+ b.HasIndex("UpdatedById");
+
+ b.ToTable("instrumentation", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.Layer", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id_lay");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("AlterationId")
+ .HasColumnType("integer")
+ .HasColumnName("alteration_id_cli");
+
+ b.Property("CohesionId")
+ .HasColumnType("integer")
+ .HasColumnName("cohesion_id_cli");
+
+ b.Property("CompactnessId")
+ .HasColumnType("integer")
+ .HasColumnName("compactness_id_cli");
+
+ b.Property("ConsistanceId")
+ .HasColumnType("integer")
+ .HasColumnName("consistance_id_cli");
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("creation_lay");
+
+ b.Property("CreatedById")
+ .HasColumnType("integer")
+ .HasColumnName("creator_lay");
+
+ b.Property("DescriptionQualityId")
+ .HasColumnType("integer")
+ .HasColumnName("qt_description_id_cli");
+
+ b.Property("FromDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("depth_from_lay");
+
+ b.Property("GradationId")
+ .HasColumnType("integer")
+ .HasColumnName("gradation_id_cli");
+
+ b.Property("GrainSize1Id")
+ .HasColumnType("integer")
+ .HasColumnName("grain_size_1_id_cli");
+
+ b.Property("GrainSize2Id")
+ .HasColumnType("integer")
+ .HasColumnName("grain_size_2_id_cli");
+
+ b.Property("HumidityId")
+ .HasColumnType("integer")
+ .HasColumnName("humidity_id_cli");
+
+ b.Property("IsLast")
+ .HasColumnType("boolean")
+ .HasColumnName("last_lay");
+
+ b.Property("IsStriae")
+ .HasColumnType("boolean")
+ .HasColumnName("striae_lay");
+
+ b.Property("IsUndefined")
+ .HasColumnType("boolean")
+ .HasColumnName("undefined_lay");
+
+ b.Property("LithologyId")
+ .HasColumnType("integer")
+ .HasColumnName("lithology_id_cli");
+
+ b.Property("LithologyTopBedrockId")
+ .HasColumnType("integer")
+ .HasColumnName("lithology_top_bedrock_id_cli");
+
+ b.Property("LithostratigraphyId")
+ .HasColumnType("integer")
+ .HasColumnName("lithostratigraphy_id_cli");
+
+ b.Property("Notes")
+ .HasColumnType("text")
+ .HasColumnName("notes_lay");
+
+ b.Property("OriginalLithology")
+ .HasColumnType("text")
+ .HasColumnName("original_lithology");
+
+ b.Property("OriginalUscs")
+ .HasColumnType("text")
+ .HasColumnName("uscs_original_lay");
+
+ b.Property("PlasticityId")
+ .HasColumnType("integer")
+ .HasColumnName("plasticity_id_cli");
+
+ b.Property("StratigraphyId")
+ .HasColumnType("integer")
+ .HasColumnName("id_sty_fk");
+
+ b.Property("ToDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("depth_to_lay");
+
+ b.Property("Updated")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("update_lay");
+
+ b.Property("UpdatedById")
+ .HasColumnType("integer")
+ .HasColumnName("updater_lay");
+
+ b.Property("Uscs1Id")
+ .HasColumnType("integer")
+ .HasColumnName("uscs_1_id_cli");
+
+ b.Property("Uscs2Id")
+ .HasColumnType("integer")
+ .HasColumnName("uscs_2_id_cli");
+
+ b.Property("UscsDeterminationId")
+ .HasColumnType("integer")
+ .HasColumnName("uscs_determination_id_cli");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AlterationId");
+
+ b.HasIndex("CohesionId");
+
+ b.HasIndex("CompactnessId");
+
+ b.HasIndex("ConsistanceId");
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("DescriptionQualityId");
+
+ b.HasIndex("GradationId");
+
+ b.HasIndex("GrainSize1Id");
+
+ b.HasIndex("GrainSize2Id");
+
+ b.HasIndex("HumidityId");
+
+ b.HasIndex("LithologyId");
+
+ b.HasIndex("LithologyTopBedrockId");
+
+ b.HasIndex("LithostratigraphyId");
+
+ b.HasIndex("PlasticityId");
+
+ b.HasIndex("StratigraphyId");
+
+ b.HasIndex("UpdatedById");
+
+ b.HasIndex("Uscs1Id");
+
+ b.HasIndex("Uscs2Id");
+
+ b.HasIndex("UscsDeterminationId");
+
+ b.ToTable("layer", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.LayerColorCode", b =>
+ {
+ b.Property("LayerId")
+ .HasColumnType("integer")
+ .HasColumnName("layer_id");
+
+ b.Property("CodelistId")
+ .HasColumnType("integer")
+ .HasColumnName("color_id");
+
+ b.HasKey("LayerId", "CodelistId");
+
+ b.HasIndex("CodelistId");
+
+ b.ToTable("layer_color_codelist", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.LayerDebrisCode", b =>
+ {
+ b.Property("LayerId")
+ .HasColumnType("integer")
+ .HasColumnName("layer_id");
+
+ b.Property("CodelistId")
+ .HasColumnType("integer")
+ .HasColumnName("debris_id");
+
+ b.HasKey("LayerId", "CodelistId");
+
+ b.HasIndex("CodelistId");
+
+ b.ToTable("layer_debris_codelist", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.LayerGrainAngularityCode", b =>
+ {
+ b.Property("LayerId")
+ .HasColumnType("integer")
+ .HasColumnName("layer_id");
+
+ b.Property("CodelistId")
+ .HasColumnType("integer")
+ .HasColumnName("grain_angularity_id");
+
+ b.HasKey("LayerId", "CodelistId");
+
+ b.HasIndex("CodelistId");
+
+ b.ToTable("layer_grain_angularity_codelist", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.LayerGrainShapeCode", b =>
+ {
+ b.Property("LayerId")
+ .HasColumnType("integer")
+ .HasColumnName("layer_id");
+
+ b.Property("CodelistId")
+ .HasColumnType("integer")
+ .HasColumnName("grain_shape_id");
+
+ b.HasKey("LayerId", "CodelistId");
+
+ b.HasIndex("CodelistId");
+
+ b.ToTable("layer_grain_shape_codelist", "bdms");
+ });
+
+ modelBuilder.Entity("BDMS.Models.LayerOrganicComponentCode", b =>
+ {
+ b.Property("LayerId")
+ .HasColumnType("integer")
+ .HasColumnName("layer_id");
+
+ b.Property