本文介绍了在EF Core中配置抽象基类而不创建表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过创建BaseEntity.cs类向每个实体添加了DateCreatedUserCreatedDateModifiedUserModified字段.我的要求是生成单个表,该表具有base类的所有字段作为列.

I have added DateCreated, UserCreated, DateModified and UserModified fields to each entity by creating a BaseEntity.cs class. My requirement is to generate single table which is having all the fields of base class as columns.

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()");
 }

我已运行以下迁移命令来创建脚本和更新数据库

I have run the below migration commands to create script and update database

Add-Migration -Name "InitialMigration" -Context "SchoolContext"
update-database

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

It has created separate tables BaseEntity and Student in the SQL Server database. My expectation is to create a single Student table with all the BaseEntity fields as columns.

如何实现?

我正在使用ASP.NET CORE2.1

推荐答案

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

According to Microsoft Documentation you can use [NotMapped] data annotation or modelBuilder.Ignore<TEntity>(); to ignore the table creation for BaseEntity as follows:

但是对于您来说,[NotMapped]不能为您提供帮助,因为Fluent API始终具有比数据注释(属性)更高的优先级.因此,您可以在OnModelCreating中的BaseEntity配置之后调用modelBuilder.Ignore<BaseEntity>();,但是调用modelBuilder.Ignore<BaseEntity>();将丢失BaseEntity配置.

But in your case [NotMapped] would not help you because Fluent API always has higher priority than the data annotations (attributes). So you can call modelBuilder.Ignore<BaseEntity>(); after the BaseEntity configuration in the OnModelCreating but calling modelBuilder.Ignore<BaseEntity>(); will lose the BaseEntity configurations.

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

So as per as I am concerned the best solution would be as follows:

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

Write the configuration for BaseEntity as follows:

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的配置:

Then write the configuration for Student as follows:

public class StudentConfigurations : BaseEntityConfigurations<Student>
{
    public override void Configure(EntityTypeBuilder<Student> builder)
    {
        base.Configure(builder); // Must call this

       // other configurations here
    }
}

然后在OnModelCreating中进行如下操作:

Then in the OnModelCreating as follows:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.ApplyConfiguration(new StudentConfigurations());
}

迁移将生成唯一具有BaseEntity配置的Student表,如下所示:

Migration will generate the only Student table with BaseEntity configuration as follows:

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);
            });

这篇关于在EF Core中配置抽象基类而不创建表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 16:57