This question already has an answer here:
Entity Framework Core 2.0: How to configure abstract base class once

(1个答案)


2年前关闭。




通过创建DateCreated类,我向每个实体添加了UserCreatedDateModifiedUserModifiedBaseEntity.cs字段。我的要求是生成单个表,该表具有base类的所有字段作为列。
public class BaseEntity
{
     public DateTime? DateCreated { get; set; }
     public string UserCreated { get; set; }
     public DateTime? DateModified { get; set; }
     public string UserModified { get; set; }
}

这是我的Student
public class Student : BaseEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

这是我的上下文课
public class SchoolContext: DbContext
{
    public LibraContext(DbContextOptions<SchoolContext> options)
        : base(options)
    { }

    public DbSet<Student> Students { get; set; }
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
        //CreatedDate
        modelBuilder.Entity<BaseEntity>().Property(x => x.DateCreated).HasDefaultValueSql("GETDATE()");
        //Updated Date
        modelBuilder.Entity<BaseEntity>().Property(x => x.DateModified).HasDefaultValueSql("GETDATE()");
 }

我已经运行以下迁移命令来创建脚本和更新数据库
Add-Migration -Name "InitialMigration" -Context "SchoolContext"
update-database

它已在SQL Server数据库中创建了单独的表BaseEntityStudent。我的期望是创建一个包含所有Student字段作为列的BaseEntity表。

如何实现呢?

我正在使用ASP.NET CORE2.1

最佳答案

根据Microsoft Documentation,可以使用[NotMapped]数据注释或modelBuilder.Ignore<TEntity>();忽略BaseEntity的表创建,如下所示:

但是在您的情况下,[NotMapped]对您无济于事,因为Fluent API始终具有比数据注释(属性)更高的优先级。因此,您可以在modelBuilder.Ignore<BaseEntity>();中的BaseEntity配置之后调用OnModelCreating,但是调用modelBuilder.Ignore<BaseEntity>();将丢失BaseEntity配置。

因此,据我所知,最佳解决方案如下:

编写BaseEntity的配置,如下所示:

public class BaseEntityConfigurations<TEntity> : IEntityTypeConfiguration<TEntity> where TEntity : BaseEntity
{
    public virtual void Configure(EntityTypeBuilder<TEntity> builder)
    {
        //CreatedDate
        builder.Property(x => x.DateCreated).HasDefaultValueSql("GETDATE()");
        //Updated Date
        builder.Property(x => x.DateModified).HasDefaultValueSql("GETDATE()");
    }
}

然后,按如下所示编写Student的配置:
public class StudentConfigurations : BaseEntityConfigurations<Student>
{
    public override void Configure(EntityTypeBuilder<Student> builder)
    {
        base.Configure(builder); // Must call this

       // other configurations here
    }
}

然后在OnModelCreating中如下所示:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.ApplyConfiguration(new StudentConfigurations());
}

迁移将生成唯一具有Student配置的BaseEntity表,如下所示:
migrationBuilder.CreateTable(
            name: "Students",
            columns: table => new
            {
                Id = table.Column<int>(nullable: false)
                    .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                DateCreated = table.Column<DateTime>(nullable: true, defaultValueSql: "GETDATE()"),
                UserCreated = table.Column<string>(nullable: true),
                DateModified = table.Column<DateTime>(nullable: true, defaultValueSql: "GETDATE()"),
                UserModified = table.Column<string>(nullable: true),
                Name = table.Column<string>(nullable: true)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Students", x => x.Id);
            });

10-02 16:05