EFCore5 同一实体配置多鉴别器值及基类回退映射方案咨询
答案
EF Core 5.0.10 原生不支持为同一实体类型绑定多个鉴别器值,但可以通过新增独立阴影属性作为鉴别器的方式实现你需要的映射效果,无需修改原有实体结构。
问题原因
EF Core 默认的鉴别器映射规则要求每个鉴别器值唯一对应一个实体类型,同时每个实体类型只能绑定一个鉴别器值,因此你原有的为Issue绑定两个枚举值的配置会触发映射错误。
可行实现方案
通过新增独立的阴影属性作为专用鉴别器,不和原有Type字段耦合,配置逻辑如下:
- 在
OnModelCreating中为Issue实体新增一个阴影属性作为鉴别器,所有非Special的枚举值统一映射到基类Issue - 自定义值生成器,在数据保存时自动根据原
Type字段的值给阴影鉴别器赋值 - 原有
Type字段正常配置,不受鉴别器逻辑影响,值会完整保留
完整配置代码
protected override void OnModelCreating(ModelBuilder builder) { var issueBuilder = builder.Entity<Issue>(); // 新增阴影属性作为专用鉴别器 issueBuilder.Property<IssueType>("IssueDiscriminator"); // 配置鉴别器映射规则 issueBuilder.HasDiscriminator<IssueType>("IssueDiscriminator") .HasValue<Issue>(default) .HasValue<SpecialIssue>(IssueType.Special); // 配置鉴别器值自动生成规则 issueBuilder.Property("IssueDiscriminator") .IsRequired() .HasValueGenerator<IssueDiscriminatorGenerator>(); // 原有Type字段正常配置,不参与鉴别器逻辑 issueBuilder.Property(x => x.Type).IsRequired(); } // 鉴别器值自动生成器 internal class IssueDiscriminatorGenerator : ValueGenerator<IssueType> { public override bool GeneratesTemporaryValues => false; public override IssueType Next(EntityEntry entry) { if (entry.Entity is Issue issue) { return issue.Type == IssueType.Special ? IssueType.Special : default; } return default; } }
验证效果
- 当
Type为Special时,EF会自动实例化SpecialIssue子类,Payload字段正常映射 - 当
Type为First、Second或其他后续新增的枚举值时,EF会自动实例化基类Issue,原有Type字段的值完全保留 - 所有数据存储在同一张
Issues表中,符合你的需求
内容的提问来源于stack exchange,提问作者TorbenJ
相关产品推荐
相关产品推荐

