如何在EF Core 2.0的OnModelCreating中基于继承生成对象属性创建模型?
在EF Core 2.0中通过继承基类生成模型属性的实现方案
我来帮你梳理下怎么在EF Core 2.0里,借助OnModelCreating方法实现基类属性的复用和模型配置。针对你的场景,核心是利用EF Core的继承映射能力,把DbDateTime的公共属性自动映射到派生实体的数据库表中,同时还能统一配置这些属性的规则。
第一步:调整基类(推荐但非强制)
首先把DbDateTime设为抽象类,这样EF Core就不会把它当成独立的实体生成额外的数据库表,它仅作为共享属性的载体:
public abstract class DbDateTime { public DateTimeOffset CreatedDateTime { get; set; } public DateTimeOffset LastModifiedDateTime { get; set; } }
你的派生类保持不变:
public class MyTable : DbDateTime { public string Id { get; set; } public string Prop1 { get; set; } // 其他业务属性... }
第二步:在DbContext中配置继承与属性规则
在继承自DbContext的类中,除了声明派生类的DbSet,还需要在OnModelCreating里明确继承关系,并可以统一配置基类属性的数据库规则:
public class MyDbContext : DbContext { // 声明派生类的DbSet public DbSet<MyTable> MyTables { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 1. 显式配置继承关系(EF Core 2.0会自动识别继承,但显式配置更清晰) modelBuilder.Entity<MyTable>() .HasBaseType<DbDateTime>(); // 2. 统一配置基类属性的数据库规则(所有继承自DbDateTime的实体都会生效) modelBuilder.Entity<DbDateTime>() .Property(x => x.CreatedDateTime) .HasColumnName("CreatedAt") // 自定义数据库列名 .IsRequired() .HasDefaultValueSql("GETUTCDATE()"); // 新增时自动设为当前UTC时间 modelBuilder.Entity<DbDateTime>() .Property(x => x.LastModifiedDateTime) .HasColumnName("UpdatedAt") .IsRequired() .HasDefaultValueSql("GETUTCDATE()"); // 其他模型配置... } // 可选:重写SaveChanges,自动维护时间戳 public override int SaveChanges() { UpdateTimestamps(); return base.SaveChanges(); } public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default) { UpdateTimestamps(); return base.SaveChangesAsync(cancellationToken); } private void UpdateTimestamps() { // 自动更新所有DbDateTime派生类的时间戳 var timestampEntries = ChangeTracker.Entries<DbDateTime>() .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified); foreach (var entry in timestampEntries) { if (entry.State == EntityState.Added) { entry.Entity.CreatedDateTime = DateTimeOffset.UtcNow; } entry.Entity.LastModifiedDateTime = DateTimeOffset.UtcNow; } } }
关键说明
- 继承映射模式:EF Core 2.0默认使用TPH(每个层次结构一张表),也就是
MyTable的数据库表会包含Id、Prop1以及来自DbDateTime的CreatedDateTime、LastModifiedDateTime所有属性,不需要额外创建基类对应的表。 - 统一配置的优势:通过
modelBuilder.Entity<DbDateTime>配置的规则,会自动应用到所有继承它的实体上,避免了每个实体重复配置时间戳属性的麻烦。 - 自动维护时间戳:重写
SaveChanges方法后,新增或修改实体时会自动更新时间戳,不需要手动赋值,简化业务代码。
内容的提问来源于stack exchange,提问作者jacobohunter
相关产品推荐
相关产品推荐

