diff --git a/Artskart3.Api/Controllers/LookupController.cs b/Artskart3.Api/Controllers/LookupController.cs
index 22e5ee8f..25911b58 100644
--- a/Artskart3.Api/Controllers/LookupController.cs
+++ b/Artskart3.Api/Controllers/LookupController.cs
@@ -11,10 +11,12 @@ namespace Artskart3.Api.Controllers;
public class LookupController : ControllerBase
{
private readonly ILookupService _lookupService;
+ private readonly ITaxonHierarchyService _taxonHierarchy;
- public LookupController(ILookupService lookupService)
+ public LookupController(ILookupService lookupService, ITaxonHierarchyService taxonHierarchy)
{
_lookupService = lookupService ?? throw new ArgumentNullException(nameof(lookupService));
+ _taxonHierarchy = taxonHierarchy ?? throw new ArgumentNullException(nameof(taxonHierarchy));
}
///
@@ -82,4 +84,17 @@ public async Task>> GetBasisOfRecords
var basisOfRecords = await _lookupService.GetBasisOfRecordsAsync(cancellationToken);
return Ok(basisOfRecords);
}
+
+ ///
+ /// Returnerer direkte barn i taksonomien for en gitt forelder-taxon.
+ /// Uten parentTaxonId returneres rotnodene (kingdom-nivå).
+ /// Data hentes fra minne — ingen databasekall per request.
+ ///
+ [HttpGet("TaxonTree")]
+ [Produces("application/json")]
+ public ActionResult> GetTaxonTree([FromQuery] int? parentTaxonId = null, CancellationToken cancellationToken = default)
+ {
+ var children = _taxonHierarchy.GetChildren(parentTaxonId);
+ return Ok(children);
+ }
}
diff --git a/Artskart3.Api/Controllers/SearchController.cs b/Artskart3.Api/Controllers/SearchController.cs
index b1465e65..7e607fd1 100644
--- a/Artskart3.Api/Controllers/SearchController.cs
+++ b/Artskart3.Api/Controllers/SearchController.cs
@@ -277,6 +277,7 @@ private bool ValidateFilterArraySizes(ObservationSearchFilterDto filter, out Bad
ReadOnlySpan<(string name, int? length)> arrays =
[
(nameof(filter.TaxonGroupIds), filter.TaxonGroupIds?.Length),
+ (nameof(filter.TaxonIds), filter.TaxonIds?.Length),
(nameof(filter.CategoryIds), filter.CategoryIds?.Length),
(nameof(filter.OrganizationIds), filter.OrganizationIds?.Length),
(nameof(filter.MunicipalityIds), filter.MunicipalityIds?.Length),
@@ -343,6 +344,7 @@ private bool ValidateLocationFilterArraySizes(LocationSearchFilterDto filter, ou
ReadOnlySpan<(string name, int? length)> arrays =
[
(nameof(filter.TaxonGroupIds), filter.TaxonGroupIds?.Length),
+ (nameof(filter.TaxonIds), filter.TaxonIds?.Length),
(nameof(filter.CategoryIds), filter.CategoryIds?.Length),
(nameof(filter.OrganizationIds), filter.OrganizationIds?.Length),
(nameof(filter.MunicipalityIds), filter.MunicipalityIds?.Length),
diff --git a/Artskart3.Core/Application/DTOs/IObservationFilter.cs b/Artskart3.Core/Application/DTOs/IObservationFilter.cs
index ef088e34..bba97b29 100644
--- a/Artskart3.Core/Application/DTOs/IObservationFilter.cs
+++ b/Artskart3.Core/Application/DTOs/IObservationFilter.cs
@@ -7,6 +7,7 @@ namespace Artskart3.Core.Application.DTOs;
public interface IObservationFilter
{
int[]? TaxonGroupIds { get; }
+ int[]? TaxonIds { get; }
int[]? CategoryIds { get; }
int[]? OrganizationIds { get; }
string[]? MunicipalityIds { get; }
diff --git a/Artskart3.Core/Application/DTOs/LocationSearchFilterDto.cs b/Artskart3.Core/Application/DTOs/LocationSearchFilterDto.cs
index 2c517fb7..b1f2831e 100644
--- a/Artskart3.Core/Application/DTOs/LocationSearchFilterDto.cs
+++ b/Artskart3.Core/Application/DTOs/LocationSearchFilterDto.cs
@@ -4,6 +4,8 @@ public class LocationSearchFilterDto : IObservationFilter
{
public int[]? TaxonGroupIds { get; set; }
+ public int[]? TaxonIds { get; set; }
+
public int[]? CategoryIds { get; set; }
public int[]? BasisOfRecordIds { get; set; }
@@ -29,6 +31,7 @@ public class LocationSearchFilterDto : IObservationFilter
///
public bool HasActiveFilters =>
TaxonGroupIds?.Length > 0 ||
+ TaxonIds?.Length > 0 ||
CategoryIds?.Length > 0 ||
BasisOfRecordIds?.Length > 0 ||
OrganizationIds?.Length > 0 ||
@@ -50,6 +53,7 @@ public class LocationSearchFilterDto : IObservationFilter
///
public bool HasObservationAttributeFilters =>
TaxonGroupIds?.Length > 0 ||
+ TaxonIds?.Length > 0 ||
CategoryIds?.Length > 0 ||
BasisOfRecordIds?.Length > 0 ||
OrganizationIds?.Length > 0 ||
diff --git a/Artskart3.Core/Application/DTOs/ObservationSearchFilterDto.cs b/Artskart3.Core/Application/DTOs/ObservationSearchFilterDto.cs
index 05e8e875..a51f8c04 100644
--- a/Artskart3.Core/Application/DTOs/ObservationSearchFilterDto.cs
+++ b/Artskart3.Core/Application/DTOs/ObservationSearchFilterDto.cs
@@ -10,6 +10,8 @@ public class ObservationSearchFilterDto : PaginatedRequestDto, IObservationFilte
public int[]? TaxonGroupIds { get; set; }
+ public int[]? TaxonIds { get; set; }
+
public int[]? CategoryIds { get; set; }
public int[]? OrganizationIds { get; set; }
diff --git a/Artskart3.Core/Application/DTOs/TaxonTreeNodeDto.cs b/Artskart3.Core/Application/DTOs/TaxonTreeNodeDto.cs
new file mode 100644
index 00000000..543aa216
--- /dev/null
+++ b/Artskart3.Core/Application/DTOs/TaxonTreeNodeDto.cs
@@ -0,0 +1,14 @@
+namespace Artskart3.Core.Application.DTOs;
+
+public class TaxonTreeNodeDto
+{
+ public int Id { get; set; }
+ public string? ValidScientificName { get; set; }
+ public string? PreferredPopularName { get; set; }
+ public int TaxonRankId { get; set; }
+ public int TaxonGroupId { get; set; }
+ public int? CumulativeObservationCount { get; set; }
+ public bool ExistsInCountry { get; set; }
+ public bool HasChildren { get; set; }
+ public List Children { get; set; } = [];
+}
diff --git a/Artskart3.Core/Application/Services/Interfaces/ITaxonHierarchyService.cs b/Artskart3.Core/Application/Services/Interfaces/ITaxonHierarchyService.cs
new file mode 100644
index 00000000..858e794c
--- /dev/null
+++ b/Artskart3.Core/Application/Services/Interfaces/ITaxonHierarchyService.cs
@@ -0,0 +1,23 @@
+using Artskart3.Core.Application.DTOs;
+
+namespace Artskart3.Core.Application.Services.Interfaces;
+
+///
+/// Oppstartslastet oppslag for taksonhierarki.
+/// Data lastes fra Taxon-tabellen og holdes i minne, oppdateres periodisk.
+///
+public interface ITaxonHierarchyService
+{
+ ///
+ /// Returnerer TaxonRankId for et gitt taxonId, eller null hvis ukjent.
+ /// Brukes for å bestemme hvilken kolonne i ObservationTaxonHierarchy som skal spørres.
+ ///
+ int? GetTaxonRankId(int taxonId);
+
+ ///
+ /// Returnerer direkte barn av en gitt taxon som trenoder.
+ /// Hvis parentTaxonId er null, returneres rotnodene (kingdom-nivå).
+ /// Filtrerer til kun taxoner med observasjoner eller som finnes i landet.
+ ///
+ List GetChildren(int? parentTaxonId);
+}
diff --git a/Artskart3.Core/Domain/Entities/ObservationTaxonHierarchy.cs b/Artskart3.Core/Domain/Entities/ObservationTaxonHierarchy.cs
new file mode 100644
index 00000000..312325c4
--- /dev/null
+++ b/Artskart3.Core/Domain/Entities/ObservationTaxonHierarchy.cs
@@ -0,0 +1,38 @@
+namespace Artskart3.Core.Domain.Entities;
+
+///
+/// Denormalisert hierarkitabell for raske taksonomiske oppslag.
+/// Hver rad knytter en observasjon til alle sine forfedre i taksonomien,
+/// med én kolonne per rangsnivå (kingdom, phylum, class, osv.).
+///
+public class ObservationTaxonHierarchy
+{
+ public int ObservationId { get; set; }
+
+ public int? KingdomTaxonId { get; set; } // TaxonRankId 1
+ public int? SubkingdomTaxonId { get; set; } // TaxonRankId 2
+ public int? PhylumTaxonId { get; set; } // TaxonRankId 3
+ public int? SubphylumTaxonId { get; set; } // TaxonRankId 4
+ public int? SuperclassTaxonId { get; set; } // TaxonRankId 5
+ public int? ClassTaxonId { get; set; } // TaxonRankId 6
+ public int? SubclassTaxonId { get; set; } // TaxonRankId 7
+ public int? InfraclassTaxonId { get; set; } // TaxonRankId 8
+ public int? CohortTaxonId { get; set; } // TaxonRankId 9
+ public int? SuperorderTaxonId { get; set; } // TaxonRankId 10
+ public int? OrderTaxonId { get; set; } // TaxonRankId 11
+ public int? SuborderTaxonId { get; set; } // TaxonRankId 12
+ public int? InfraorderTaxonId { get; set; } // TaxonRankId 13
+ public int? SuperfamilyTaxonId { get; set; } // TaxonRankId 14
+ public int? FamilyTaxonId { get; set; } // TaxonRankId 15
+ public int? SubfamilyTaxonId { get; set; } // TaxonRankId 16
+ public int? TribeTaxonId { get; set; } // TaxonRankId 17
+ public int? SubtribeTaxonId { get; set; } // TaxonRankId 18
+ public int? GenusTaxonId { get; set; } // TaxonRankId 19
+ public int? SubgenusTaxonId { get; set; } // TaxonRankId 20
+ public int? SectionTaxonId { get; set; } // TaxonRankId 21
+ public int? SpeciesTaxonId { get; set; } // TaxonRankId 22
+ public int? SubspeciesTaxonId { get; set; } // TaxonRankId 23
+ public int? VarietyTaxonId { get; set; } // TaxonRankId 24
+ public int? FormTaxonId { get; set; } // TaxonRankId 25
+ public int? NotSetTaxonId { get; set; } // TaxonRankId 26
+}
diff --git a/Artskart3.Infrastructure/Data/DbContext/ArtskartDbContext.cs b/Artskart3.Infrastructure/Data/DbContext/ArtskartDbContext.cs
index ba2a015f..aba476e0 100644
--- a/Artskart3.Infrastructure/Data/DbContext/ArtskartDbContext.cs
+++ b/Artskart3.Infrastructure/Data/DbContext/ArtskartDbContext.cs
@@ -1024,6 +1024,40 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
entity.HasIndex(e => new { e.EntityTypeId, e.EntityId, e.ObservationId }).HasDatabaseName("IX_ObservationEntityIndex_EntityType_EntityId_ObsId");
});
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.ObservationId);
+ entity.Property(e => e.ObservationId).ValueGeneratedNever();
+ entity.ToTable("ObservationTaxonHierarchy");
+
+ entity.HasIndex(e => e.KingdomTaxonId).HasDatabaseName("IX_OTH_Kingdom").HasFilter("[KingdomTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.SubkingdomTaxonId).HasDatabaseName("IX_OTH_Subkingdom").HasFilter("[SubkingdomTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.PhylumTaxonId).HasDatabaseName("IX_OTH_Phylum").HasFilter("[PhylumTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.SubphylumTaxonId).HasDatabaseName("IX_OTH_Subphylum").HasFilter("[SubphylumTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.SuperclassTaxonId).HasDatabaseName("IX_OTH_Superclass").HasFilter("[SuperclassTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.ClassTaxonId).HasDatabaseName("IX_OTH_Class").HasFilter("[ClassTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.SubclassTaxonId).HasDatabaseName("IX_OTH_Subclass").HasFilter("[SubclassTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.InfraclassTaxonId).HasDatabaseName("IX_OTH_Infraclass").HasFilter("[InfraclassTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.CohortTaxonId).HasDatabaseName("IX_OTH_Cohort").HasFilter("[CohortTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.SuperorderTaxonId).HasDatabaseName("IX_OTH_Superorder").HasFilter("[SuperorderTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.OrderTaxonId).HasDatabaseName("IX_OTH_Order").HasFilter("[OrderTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.SuborderTaxonId).HasDatabaseName("IX_OTH_Suborder").HasFilter("[SuborderTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.InfraorderTaxonId).HasDatabaseName("IX_OTH_Infraorder").HasFilter("[InfraorderTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.SuperfamilyTaxonId).HasDatabaseName("IX_OTH_Superfamily").HasFilter("[SuperfamilyTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.FamilyTaxonId).HasDatabaseName("IX_OTH_Family").HasFilter("[FamilyTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.SubfamilyTaxonId).HasDatabaseName("IX_OTH_Subfamily").HasFilter("[SubfamilyTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.TribeTaxonId).HasDatabaseName("IX_OTH_Tribe").HasFilter("[TribeTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.SubtribeTaxonId).HasDatabaseName("IX_OTH_Subtribe").HasFilter("[SubtribeTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.GenusTaxonId).HasDatabaseName("IX_OTH_Genus").HasFilter("[GenusTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.SubgenusTaxonId).HasDatabaseName("IX_OTH_Subgenus").HasFilter("[SubgenusTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.SectionTaxonId).HasDatabaseName("IX_OTH_Section").HasFilter("[SectionTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.SpeciesTaxonId).HasDatabaseName("IX_OTH_Species").HasFilter("[SpeciesTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.SubspeciesTaxonId).HasDatabaseName("IX_OTH_Subspecies").HasFilter("[SubspeciesTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.VarietyTaxonId).HasDatabaseName("IX_OTH_Variety").HasFilter("[VarietyTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.FormTaxonId).HasDatabaseName("IX_OTH_Form").HasFilter("[FormTaxonId] IS NOT NULL");
+ entity.HasIndex(e => e.NotSetTaxonId).HasDatabaseName("IX_OTH_NotSet").HasFilter("[NotSetTaxonId] IS NOT NULL");
+ });
+
OnModelCreatingPartial(modelBuilder);
}
diff --git a/Artskart3.Infrastructure/DependencyInjection/ServiceCollectionExtensions.cs b/Artskart3.Infrastructure/DependencyInjection/ServiceCollectionExtensions.cs
index 45e52963..0fadda54 100644
--- a/Artskart3.Infrastructure/DependencyInjection/ServiceCollectionExtensions.cs
+++ b/Artskart3.Infrastructure/DependencyInjection/ServiceCollectionExtensions.cs
@@ -24,6 +24,9 @@ public static IServiceCollection AddApplicationServices(this IServiceCollection
services.AddSingleton();
services.AddSingleton(sp => sp.GetRequiredService());
services.AddHostedService(sp => sp.GetRequiredService());
+ services.AddSingleton();
+ services.AddSingleton(sp => sp.GetRequiredService());
+ services.AddHostedService(sp => sp.GetRequiredService());
services.AddScoped();
services.AddScoped();
services.AddScoped();
diff --git a/Artskart3.Infrastructure/Migrations/20260702113806_AddObservationTaxonHierarchy.Designer.cs b/Artskart3.Infrastructure/Migrations/20260702113806_AddObservationTaxonHierarchy.Designer.cs
new file mode 100644
index 00000000..e5038c0f
--- /dev/null
+++ b/Artskart3.Infrastructure/Migrations/20260702113806_AddObservationTaxonHierarchy.Designer.cs
@@ -0,0 +1,3153 @@
+//
+using System;
+using Artskart3.Infrastructure.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using NetTopologySuite.Geometries;
+
+#nullable disable
+
+namespace Artskart3.Infrastructure.Migrations
+{
+ [DbContext(typeof(ArtskartDbContext))]
+ [Migration("20260702113806_AddObservationTaxonHierarchy")]
+ partial class AddObservationTaxonHierarchy
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "10.0.7")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.Area", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("AreaTypeId")
+ .HasColumnType("int");
+
+ b.Property("Bbox")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("Centroid")
+ .ValueGeneratedOnAddOrUpdate()
+ .HasColumnType("geometry")
+ .HasComputedColumnSql("([WktPolygon].[STCentroid]())", false);
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DocumentId")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("Fid")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("IsCurrent")
+ .HasColumnType("bit");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("ObservationCount")
+ .HasColumnType("int");
+
+ b.Property("ParentFid")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("SyncDateTime")
+ .HasColumnType("datetime");
+
+ b.Property("TimeStamp")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("datetime")
+ .HasDefaultValue(new DateTime(1900, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("WktPolygon")
+ .HasColumnType("geometry");
+
+ b.Property("ZoomLevel")
+ .HasColumnType("int");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.Area");
+
+ b.HasIndex(new[] { "AreaTypeId", "Id", "Fid" }, "IX_AreaTypeID");
+
+ b.HasIndex(new[] { "AreaTypeId", "Fid", "IsCurrent" }, "IX_Area_AreaTypeId_Fid_IsCurrent");
+
+ b.HasIndex(new[] { "ZoomLevel", "IsCurrent" }, "IX_Area_ZoomLevel_IsCurrent");
+
+ b.HasIndex(new[] { "Fid" }, "IX_Fid");
+
+ b.HasIndex(new[] { "ParentFid" }, "IX_ParentFid");
+
+ b.HasIndex(new[] { "Name" }, "NonClusteredIndex-20180305-111522");
+
+ b.ToTable("Area", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.AreaType", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("int");
+
+ b.Property("CategoryName")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("IsRequired")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.AreaType");
+
+ b.ToTable("AreaType", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.BasisOfRecord", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("Description")
+ .HasMaxLength(30)
+ .HasColumnType("nvarchar(30)");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(60)
+ .HasColumnType("nvarchar(60)");
+
+ b.Property("ObservationCount")
+ .HasColumnType("int");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("Variants")
+ .IsRequired()
+ .HasMaxLength(300)
+ .HasColumnType("nvarchar(300)");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.BasisOfRecord");
+
+ b.ToTable("BasisOfRecord", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.Behavior", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("Description")
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(60)
+ .HasColumnType("nvarchar(60)");
+
+ b.Property("ObservationCount")
+ .HasColumnType("int");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("Variants")
+ .IsRequired()
+ .HasMaxLength(300)
+ .HasColumnType("nvarchar(300)");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.Behavior");
+
+ b.ToTable("Behavior", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.Category", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("int");
+
+ b.Property("CategoryTypeId")
+ .HasColumnType("int");
+
+ b.Property("Code")
+ .IsRequired()
+ .HasMaxLength(2)
+ .HasColumnType("nvarchar(2)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("ObservationCount")
+ .HasColumnType("int");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.Category");
+
+ b.HasIndex(new[] { "CategoryTypeId" }, "IX_CategoryTypeId");
+
+ b.ToTable("Category", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.CategoryType", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(60)
+ .HasColumnType("nvarchar(60)");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.CategoryType");
+
+ b.ToTable("CategoryType", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.CommandLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("ID");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Command")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CommandType")
+ .IsRequired()
+ .HasMaxLength(60)
+ .HasColumnType("nvarchar(60)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DatabaseName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("EndTime")
+ .HasColumnType("datetime2");
+
+ b.Property("ErrorMessage")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ErrorNumber")
+ .HasColumnType("int");
+
+ b.Property("ExtendedInfo")
+ .HasColumnType("xml");
+
+ b.Property("IndexName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("IndexType")
+ .HasColumnType("tinyint");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("ObjectName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ObjectType")
+ .HasMaxLength(2)
+ .IsUnicode(false)
+ .HasColumnType("char(2)")
+ .IsFixedLength();
+
+ b.Property("PartitionNumber")
+ .HasColumnType("int");
+
+ b.Property("SchemaName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("StartTime")
+ .HasColumnType("datetime2");
+
+ b.Property("StatisticsName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id");
+
+ b.ToTable("CommandLog", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.DeletedItem", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("RecordId")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("ReplicationId")
+ .HasColumnType("int");
+
+ b.Property("TimeStamp")
+ .HasColumnType("datetime");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.DeletedItem");
+
+ b.HasIndex(new[] { "RecordId" }, "Ix_RecordId");
+
+ b.HasIndex(new[] { "TimeStamp" }, "Ix_TimeStamp");
+
+ b.HasIndex(new[] { "TimeStamp" }, "Ix_TimeStampWithRecordId");
+
+ b.ToTable("DeletedItem", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.ExportStatus", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("Doi")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ExportCreated")
+ .HasColumnType("datetime2");
+
+ b.Property("ExportFinished")
+ .HasColumnType("datetime2");
+
+ b.Property("ExportInfo")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ExportJobId")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ExportStarted")
+ .HasColumnType("datetime2");
+
+ b.Property("FileSize")
+ .HasColumnType("bigint");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("StatusCode")
+ .HasColumnType("int");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.ExportStatus");
+
+ b.ToTable("ExportStatus", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.Fab4exclude", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.FAB4Exclude");
+
+ b.ToTable("FAB4Exclude", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.Filter", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("SerializedFilter")
+ .IsRequired()
+ .HasMaxLength(3700)
+ .HasColumnType("nvarchar(3700)");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.Filter");
+
+ b.ToTable("Filter", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.GeometryColumn", b =>
+ {
+ b.Property("FTableCatalog")
+ .HasMaxLength(128)
+ .IsUnicode(false)
+ .HasColumnType("varchar(128)")
+ .HasColumnName("f_table_catalog");
+
+ b.Property("FTableSchema")
+ .HasMaxLength(128)
+ .IsUnicode(false)
+ .HasColumnType("varchar(128)")
+ .HasColumnName("f_table_schema");
+
+ b.Property("FTableName")
+ .HasMaxLength(256)
+ .IsUnicode(false)
+ .HasColumnType("varchar(256)")
+ .HasColumnName("f_table_name");
+
+ b.Property("FGeometryColumn")
+ .HasMaxLength(256)
+ .IsUnicode(false)
+ .HasColumnType("varchar(256)")
+ .HasColumnName("f_geometry_column");
+
+ b.Property("CoordDimension")
+ .HasColumnType("int")
+ .HasColumnName("coord_dimension");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("GeometryType")
+ .IsRequired()
+ .HasMaxLength(30)
+ .IsUnicode(false)
+ .HasColumnType("varchar(30)")
+ .HasColumnName("geometry_type");
+
+ b.Property("Id")
+ .HasColumnType("int");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("Srid")
+ .HasColumnType("int")
+ .HasColumnName("srid");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("FTableCatalog", "FTableSchema", "FTableName", "FGeometryColumn")
+ .HasName("geometry_columns_pk");
+
+ b.ToTable("geometry_columns", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.ImportLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("ModeCommand")
+ .HasColumnType("int")
+ .HasColumnName("Mode_Command");
+
+ b.Property("ModeDataset")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("Mode_Dataset");
+
+ b.Property("ModeFilePath")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("Mode_FilePath");
+
+ b.Property("ModePartitionYear")
+ .HasColumnType("int")
+ .HasColumnName("Mode_PartitionYear");
+
+ b.Property("ModeProcessMode")
+ .HasColumnType("int")
+ .HasColumnName("Mode_ProcessMode");
+
+ b.Property("ModeSensitiveRecords")
+ .HasColumnType("bit")
+ .HasColumnName("Mode_SensitiveRecords");
+
+ b.Property("Runtime")
+ .HasColumnType("float");
+
+ b.Property("SerializedObject")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("SumNewRecordsImported")
+ .HasColumnType("int");
+
+ b.Property("SumRecordsDeleted")
+ .HasColumnType("int");
+
+ b.Property("SumRecordsProcessed")
+ .HasColumnType("int");
+
+ b.Property("SumRecordsRejected")
+ .HasColumnType("int");
+
+ b.Property("SumUpdatedRecords")
+ .HasColumnType("int");
+
+ b.Property("Timestamp")
+ .HasColumnType("datetime2");
+
+ b.Property("TimestampFinished")
+ .HasColumnType("datetime2");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.ImportLog");
+
+ b.HasIndex(new[] { "Timestamp" }, "Ix_Time");
+
+ b.ToTable("ImportLog", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.ImportNotification", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("Message")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Severity")
+ .HasColumnType("int");
+
+ b.Property("SeverityDescription")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("Subject")
+ .IsRequired()
+ .HasMaxLength(250)
+ .HasColumnType("nvarchar(250)");
+
+ b.Property("Timestamp")
+ .HasColumnType("datetime2");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.ImportNotification");
+
+ b.HasIndex(new[] { "Timestamp" }, "IX_TimeStamp");
+
+ b.ToTable("ImportNotification", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.ImportState", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DateLastProcessed")
+ .HasColumnType("datetime2");
+
+ b.Property("DateLastProcessedFinished")
+ .HasColumnType("datetime2");
+
+ b.Property("DateLastProcessedWithChangeInRecords")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("Doi")
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("FailCount")
+ .HasColumnType("int");
+
+ b.Property("GbifDataSetId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ImportedNumberOfRecords")
+ .HasColumnType("int");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("LastProcessResult")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastRecordDateLastModified")
+ .HasColumnType("datetime2");
+
+ b.Property("LastRecordImportedCatalogNumber")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Name")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RejectedNumberOfRecords")
+ .HasColumnType("int");
+
+ b.Property("ReportedLastTrackDateInCache")
+ .HasColumnType("datetime2");
+
+ b.Property("ReportedTotalNumberOfRecordsInCache")
+ .HasColumnType("int");
+
+ b.Property("TrackDateOfLastRecordProcessed")
+ .HasColumnType("datetime2");
+
+ b.Property("UpdateMode")
+ .HasColumnType("int");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.ImportState");
+
+ b.ToTable("ImportState", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.Location", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CoordinatePrecision")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("East")
+ .HasColumnType("int");
+
+ b.Property("Geometry")
+ .HasColumnType("geometry");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("Latitude")
+ .HasColumnType("float");
+
+ b.Property("Locality")
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("LocationId")
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("Longitude")
+ .HasColumnType("float");
+
+ b.Property("LookupId")
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("NodeId")
+ .HasColumnType("int");
+
+ b.Property("North")
+ .HasColumnType("int");
+
+ b.Property("TimeStamp")
+ .HasColumnType("datetime");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.Location");
+
+ b.HasIndex(new[] { "CoordinatePrecision" }, "IX_CoordinatePrecision");
+
+ b.HasIndex(new[] { "East", "North" }, "IX_EastNorth");
+
+ b.HasIndex(new[] { "East" }, "IX_EastNorthGeom");
+
+ b.HasIndex(new[] { "LookupId" }, "IX_LookupId");
+
+ b.ToTable("Location", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.Maskeringsruter16x16km", b =>
+ {
+ b.Property("Objectid")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("OBJECTID");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Objectid"));
+
+ b.Property("KriteriumMaskeringsrute")
+ .HasColumnType("int")
+ .HasColumnName("KRITERIUM_MASKERINGSRUTE");
+
+ b.Property("Ruteid")
+ .HasMaxLength(50)
+ .IsUnicode(false)
+ .HasColumnType("char(50)")
+ .HasColumnName("RUTEID")
+ .IsFixedLength();
+
+ b.Property("Shape")
+ .HasColumnType("geometry")
+ .HasColumnName("SHAPE");
+
+ b.HasKey("Objectid");
+
+ b.ToTable("Maskeringsruter_16x16km", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.Maskeringsruter4x4km", b =>
+ {
+ b.Property("Objectid")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("OBJECTID");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Objectid"));
+
+ b.Property("KriteriumMaskeringsrute")
+ .HasColumnType("int")
+ .HasColumnName("KRITERIUM_MASKERINGSRUTE");
+
+ b.Property("Ruteid")
+ .HasMaxLength(50)
+ .IsUnicode(false)
+ .HasColumnType("char(50)")
+ .HasColumnName("RUTEID")
+ .IsFixedLength();
+
+ b.Property("Shape")
+ .HasColumnType("geometry")
+ .HasColumnName("SHAPE");
+
+ b.HasKey("Objectid");
+
+ b.ToTable("Maskeringsruter_4x4km", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.Maskeringsruter8x8km", b =>
+ {
+ b.Property("Objectid")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("OBJECTID");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Objectid"));
+
+ b.Property("KriteriumMaskeringsrute")
+ .HasColumnType("int")
+ .HasColumnName("KRITERIUM_MASKERINGSRUTE");
+
+ b.Property("Ruteid")
+ .HasMaxLength(50)
+ .IsUnicode(false)
+ .HasColumnType("char(50)")
+ .HasColumnName("RUTEID")
+ .IsFixedLength();
+
+ b.Property("Shape")
+ .HasColumnType("geometry")
+ .HasColumnName("SHAPE");
+
+ b.HasKey("Objectid");
+
+ b.ToTable("Maskeringsruter_8x8km", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.MediaFile", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("Description")
+ .HasMaxLength(500)
+ .HasColumnType("nvarchar(500)");
+
+ b.Property("DownloadRetryCount")
+ .HasColumnType("int");
+
+ b.Property("Downloaded")
+ .HasColumnType("bit");
+
+ b.Property("Image")
+ .HasColumnType("varbinary(max)");
+
+ b.Property("InDownloadqueue")
+ .HasColumnType("bit");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("License")
+ .HasMaxLength(500)
+ .HasColumnType("nvarchar(500)");
+
+ b.Property("MediaFileTypeId")
+ .HasColumnType("int");
+
+ b.Property("ObservationId")
+ .HasColumnType("int")
+ .HasColumnName("Observation_Id");
+
+ b.Property("Origin")
+ .IsRequired()
+ .HasMaxLength(2000)
+ .HasColumnType("nvarchar(2000)");
+
+ b.Property("RightsHolder")
+ .HasMaxLength(500)
+ .HasColumnType("nvarchar(500)");
+
+ b.Property("Size")
+ .HasColumnType("int");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.MediaFile");
+
+ b.HasIndex("MediaFileTypeId");
+
+ b.HasIndex(new[] { "Downloaded", "MediaFileTypeId", "DownloadRetryCount" }, "IX_DownLoaded");
+
+ b.HasIndex(new[] { "ObservationId" }, "IX_Observation_Id");
+
+ b.ToTable("MediaFile", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.MediaFileType", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("DeletedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("MediaTypeName")
+ .HasMaxLength(20)
+ .HasColumnType("nvarchar(20)");
+
+ b.Property("MimeType")
+ .HasMaxLength(20)
+ .HasColumnType("nvarchar(20)");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id")
+ .HasName("PK_dbo.MediaFileType");
+
+ b.ToTable("MediaFileType", (string)null);
+ });
+
+ modelBuilder.Entity("Artskart3.Core.Domain.Entities.MigrationHistory", b =>
+ {
+ b.Property("MigrationId")
+ .HasMaxLength(150)
+ .HasColumnType("nvarchar(150)");
+
+ b.Property("ContextKey")
+ .HasMaxLength(300)
+ .HasColumnType("nvarchar(300)");
+
+ b.Property("Model")
+ .IsRequired()
+ .HasColumnType("varbinary(max)");
+
+ b.Property