-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Milestone
Description
I've found that when generating a Table Per type set of classes. (I only have a base Class and one Inherited Class at the moment)
As Below. It Duplicates the Check Contraint CK_SalesCategory_StatusId twice once on the DomainBase Table and once on the SalesCategory Table.
using System;
using System.ComponentModel.DataAnnotations.Schema;
namespace Domain.Entities
{
public abstract class DomainBase
{
#region Properties
public Int64 Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreatedDate { get; set; }
public String CreatedBy { get; set; }
public String LastModifiedBy { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime LastModifiedDate { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public Byte[] RowVersion { get; set; }
#endregion
}
}
using System;
using Domain.Enums;
namespace Domain.Entities
{
public class SalesCategory : DomainBase
{
public String Name { get; set; }
public String Code { get; set; }
public EntityStatus Status { get; set; }
}
}
using System;
namespace Domain.Enums
{
public enum EntityStatus : Int64
{
New = 0,
Draft = 1,
Approved = 2
}
public class EntityStatusEntity
{
public EntityStatus Id { get; set; }
public String Name { get; set; }
}
}
namespace Infrastructure.Domain.Persistence.Contexts
{
public class PolicyContext : DbContext, IPolicyContext
{
#region Members
private readonly ILoggerFactory _loggerFactory;
#endregion
#region Properties
public DbSet<DomainBase> BaseEntities { get; set; }
public DbSet<SalesCategory> SalesCategories { get; set; }
#endregion
#region Constructor
public PolicyContext(DbContextOptions contextOptions, ILoggerFactory loggerFactory) : base(contextOptions)
{
_loggerFactory = loggerFactory;
}
#endregion
#region Methods
#region Protected Methods
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseLoggerFactory(_loggerFactory);
optionsBuilder.EnableSensitiveDataLogging();
optionsBuilder.EnableDetailedErrors();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.ApplyConfiguration(new DomainBaseConfiguration())
.ApplyConfiguration(new SalesCategoryConfiguration())
.ApplyConfiguration(new EntityStatusConfiguration())
;
}
#endregion
#endregion
}
}
using Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Infrastructure.Domain.Persistence.EntityConfigurations
{
internal class DomainBaseConfiguration : IEntityTypeConfiguration<DomainBase>
{
public void Configure(EntityTypeBuilder<DomainBase> builder)
{
builder.ToTable(nameof(DomainBase),"CommonSchema");
builder.HasKey(f => f.Id);
builder.Property(f=> f.RowVersion).IsRowVersion();
builder.Property(f => f.CreatedBy).IsRequired();
builder.Property(f => f.LastModifiedBy).IsRequired();
}
}
}
using System;
using System.Linq;
using Domain.Enums;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Infrastructure.Domain.Persistence.EntityConfigurations
{
internal class EntityStatusConfiguration : IEntityTypeConfiguration<EntityStatusEntity>
{
public void Configure(EntityTypeBuilder<EntityStatusEntity> builder)
{
builder.ToTable(nameof(EntityStatus),"CommonSchema");
builder.HasKey(f => f.Id);
builder.Property(f=> f.Name).HasMaxLength(200).IsRequired();
builder.HasData(Enum.GetValues<EntityStatus>()
.Select(e => new EntityStatusEntity() { Id = e, Name = e.ToString()}));
}
}
}
using System;
using Domain.Entities;
using Domain.Enums;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Infrastructure.Domain.Persistence.EntityConfigurations
{
internal class SalesCategoryConfiguration : IEntityTypeConfiguration<SalesCategory>
{
public void Configure(EntityTypeBuilder<SalesCategory> builder)
{
builder.ToTable(nameof(SalesCategory), "PolicySchema");
builder.Property(f=> f.Name).HasMaxLength(200).IsRequired();
builder.HasIndex(f => f.Name).IsUnique();
builder.Property(f=> f.Code).HasMaxLength(2).IsFixedLength().IsRequired();
builder.Property(f => f.Status).HasColumnName("StatusId");
builder.HasCheckConstraint($"CK_{nameof(SalesCategory)}_StatusId", $"[StatusId] IN ({(Int32)EntityStatus.New},{(Int32)EntityStatus.Draft},{(Int32)EntityStatus.Approved})");
}
}
}Generated Migration
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Infrastructure.Domain.Persistence.Migrations
{
public partial class Initial : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.EnsureSchema(
name: "CommonSchema");
migrationBuilder.EnsureSchema(
name: "PolicySchema");
migrationBuilder.CreateTable(
name: "DomainBase",
schema: "CommonSchema",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
CreatedDate = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatedBy = table.Column<string>(type: "nvarchar(max)", nullable: false),
LastModifiedBy = table.Column<string>(type: "nvarchar(max)", nullable: false),
LastModifiedDate = table.Column<DateTime>(type: "datetime2", nullable: false),
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_DomainBase", x => x.Id);
table.CheckConstraint("CK_SalesCategory_StatusId", "[StatusId] IN (0,1,2)");
});
migrationBuilder.CreateTable(
name: "EntityStatus",
schema: "CommonSchema",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false),
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_EntityStatus", x => x.Id);
});
migrationBuilder.CreateTable(
name: "SalesCategory",
schema: "PolicySchema",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false),
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
Code = table.Column<string>(type: "nchar(2)", fixedLength: true, maxLength: 2, nullable: false),
StatusId = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_SalesCategory", x => x.Id);
table.CheckConstraint("CK_SalesCategory_StatusId", "[StatusId] IN (0,1,2)");
table.ForeignKey(
name: "FK_SalesCategory_DomainBase_Id",
column: x => x.Id,
principalSchema: "CommonSchema",
principalTable: "DomainBase",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.InsertData(
schema: "CommonSchema",
table: "EntityStatus",
columns: new[] { "Id", "Name" },
values: new object[] { 0L, "New" });
migrationBuilder.InsertData(
schema: "CommonSchema",
table: "EntityStatus",
columns: new[] { "Id", "Name" },
values: new object[] { 1L, "Draft" });
migrationBuilder.InsertData(
schema: "CommonSchema",
table: "EntityStatus",
columns: new[] { "Id", "Name" },
values: new object[] { 2L, "Approved" });
migrationBuilder.CreateIndex(
name: "IX_SalesCategory_Name",
schema: "PolicySchema",
table: "SalesCategory",
column: "Name",
unique: true,
filter: "[Name] IS NOT NULL");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "EntityStatus",
schema: "CommonSchema");
migrationBuilder.DropTable(
name: "SalesCategory",
schema: "PolicySchema");
migrationBuilder.DropTable(
name: "DomainBase",
schema: "CommonSchema");
}
}
}After Generating If I try to remove the migration I get
PM> Remove-Migration
Build started...
Build succeeded.
System.ArgumentException: An item with the same key has already been added. Key: Check: CK_SalesCategory_StatusId "[StatusId] IN (0,1,2)"
at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.DiffContext.AddMapping[T](T source, T target)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.DiffCollection[T](IEnumerable`1 sources, IEnumerable`1 targets, DiffContext diffContext, Func`4 diff, Func`3 add, Func`3 remove, Func`4[] predicates)+MoveNext()
at System.Linq.Enumerable.ConcatIterator`1.MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Diff(ITable source, ITable target, DiffContext diffContext)+MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.DiffCollection[T](IEnumerable`1 sources, IEnumerable`1 targets, DiffContext diffContext, Func`4 diff, Func`3 add, Func`3 remove, Func`4[] predicates)+MoveNext()
at System.Linq.Enumerable.ConcatIterator`1.MoveNext()
at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.HasDifferences(IRelationalModel source, IRelationalModel target)
at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsSc
affolder.RemoveMigration(String projectDir, String rootNamespace, Boolean force, String language)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.RemoveMigration(String contextType, Boolean force)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.RemoveMigrationImpl(String contextType, Boolean force)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.RemoveMigration.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
An item with the same key has already been added. Key: Check: CK_SalesCategory_StatusId "[StatusId] IN (0,1,2)"
PM>
EF Core version: 5.0.3
EF Core Tools version: 5.0.3
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: (e.g. .NET 5.0)
Operating system: Windows 10 Pro N Version 10.0.19042 Build 19042
IDE: Visual Studio 2019 16.8.5
tyler-boyd and anreton