EF Core:为继承自基类的所有实体配置行版本
批量配置EF Core实体的行版本(基于基类/接口)
如果你想让所有继承自BaseEntity的实体自动拥有行版本功能,可以通过以下方式实现:
1. 定义带行版本的基类(或接口)
你已经定义了包含Version属性的抽象基类,也可以用接口来获得更灵活的适配性:
方式一:基类继承
public abstract class BaseEntity { public uint Version { get; set; } } // 业务实体继承基类 public class SomeEntity1 : BaseEntity { public int Id { get; set; } } public class SomeEntity2 : BaseEntity { public int Id { get; set; } }
方式二:接口实现(可选)
如果部分实体不想继承基类但需要行版本,可以定义接口:
public interface IVersionedEntity { uint Version { get; set; } } // 基类实现接口 public abstract class BaseEntity : IVersionedEntity { public uint Version { get; set; } } // 独立实体也可直接实现接口 public class StandaloneEntity : IVersionedEntity { public int Id { get; set; } public uint Version { get; set; } }
2. 在DbContext中批量配置行版本
在OnModelCreating方法里,遍历所有符合条件的实体类型,统一配置Version属性为行版本:
class MyContext : DbContext { public DbSet<SomeEntity1> SomeEntities1 { get; set; } public DbSet<SomeEntity2> SomeEntities2 { get; set; } // 若使用独立实体,添加对应的DbSet // public DbSet<StandaloneEntity> StandaloneEntities { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 针对继承BaseEntity的实体批量配置 foreach (var entityType in modelBuilder.Model.GetEntityTypes() .Where(t => t.ClrType.IsAssignableTo(typeof(BaseEntity)))) { modelBuilder.Entity(entityType.ClrType) .Property(nameof(BaseEntity.Version)) .IsRowVersion(); } // 若用了IVersionedEntity接口,替换为以下代码 // foreach (var entityType in modelBuilder.Model.GetEntityTypes() // .Where(t => typeof(IVersionedEntity).IsAssignableFrom(t.ClrType))) // { // modelBuilder.Entity(entityType.ClrType) // .Property(nameof(IVersionedEntity.Version)) // .IsRowVersion(); // } } // 配置数据库连接 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseNpgsql("你的数据库连接字符串"); } }
关键说明
IsRowVersion()会自动将Version属性映射到PostgreSQL的xmin系统列,无需手动指定列名。- 此方式会自动扫描所有符合条件的实体,无需为每个实体单独配置,减少重复代码。
- 行版本用于并发冲突检测,当实体更新时EF Core会自动检查
Version值,不一致则抛出并发异常。
内容的提问来源于stack exchange,提问作者Parsa99
相关产品推荐
相关产品推荐

