EF Core 5 代码继承不使用数据库继承时Discriminator异常问题 #26741
报错原因
该异常由EF Core的默认继承映射策略导致:EF Core默认采用**TPH(表每层次结构)**策略存储继承体系的实体数据,会自动要求表中存在Discriminator列用于区分不同的实体类型。而EF6对抽象基类的继承处理逻辑更宽松,当仅使用子类访问表时不会强制校验该列,因此你的代码在EF6中可以正常运行。
解决方案
以下方案按需选择即可:
方案1:移除基类映射,直接映射子类到目标表
如果你的业务场景中永远只会用Child类访问TableName表,不会直接查询BaseClass,也没有其他继承自BaseClass的子类需要映射到同一张表,这是改动最小的方案:
- 给
Child类添加表映射注解:
[Table("TableName")] public class Child: BaseClass { public string SomeProp {get; set;} }
- 在
DbContext的OnModelCreating方法中忽略基类的实体映射:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 告诉EF Core不要把BaseClass当成需要映射的实体 modelBuilder.Ignore<BaseClass>(); }
方案2:显式配置Discriminator属性,不映射到实际表字段
如果需要保留BaseClass的映射逻辑、或后续可能扩展其他子类,可以手动配置Discriminator的固定值,避免EF Core校验该字段是否存在:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<BaseClass>(b => { // 配置Discriminator规则 b.HasDiscriminator<string>("Discriminator") .HasValue<Child>("Child"); }); // 设置Discriminator为固定值,插入更新时忽略该字段 modelBuilder.Entity<Child>() .Property("Discriminator") .HasValue("Child") .Metadata.SetAfterSaveBehavior(Microsoft.EntityFrameworkCore.Metadata.PropertySaveBehavior.Ignore); }
该配置下EF Core生成查询SQL时会自动带上Discriminator = 'Child'的条件,但不会要求实际表存在该字段,也不会在数据写入时操作该列。
方案3:改用TPC(表每具体类)继承策略
如果你的BaseClass是抽象类,每个子类都对应独立的单表存储,可以直接配置TPC映射策略,该策略本身就不会生成Discriminator列要求:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Child>().UseTpcMappingStrategy(); }
内容的提问来源于stack exchange,提问作者Andrey
相关产品推荐
相关产品推荐

