EF Core中两个抽象类配置一对一关系如何仅生成一个外键
解决EF Core TPH模式下两个抽象类一对一关系重复生成外键问题
问题根源
当前在每个Valuation派生类中单独配置和对应Result派生类的一对一关系,EF Core会将这些识别为完全独立的两个关联,因此会在ValuationResult表生成两个不同的外键字段。
解决方案步骤
第一步:调整基类导航属性定义
在ValuationBase中新增抽象的ValuationResult类型导航属性,让基类层面可以直接识别关联:
public abstract class ValuationBase { public Guid Id { get; internal set; } public DateTime CreationDateTime { get; internal set; } public Owner Owner { get; internal set; } // 新增基层统一导航属性 public abstract ValuationResult Result { get; } }
泛型Valuation
public abstract class Valuation<TResult> : ValuationBase where TResult : ValuationResult { public abstract ValuationType Type { get; } // 重写基类属性 public override abstract TResult Result { get; protected set; } }
第二步:统一在基类配置关联关系
修改ValuationBaseMapping,在基类层面配置和ValuationResult的一对一关联,不需要在派生类中单独配置:
public class ValuationBaseMapping : IEntityTypeConfiguration<ValuationBase> { public void Configure(EntityTypeBuilder<ValuationBase> builder) { builder.HasKey(c => c.Id); builder.HasDiscriminator() .HasValue<ScoringCardValuation>(nameof(ScoringCardValuation)) .HasValue<FirstChicagoValuation>(nameof(FirstChicagoValuation)); builder.OwnsOne(i => i.Owner); // 统一配置两个抽象基类间的一对一关系 builder.HasOne<ValuationResult>(c => c.Result) .WithOne() .HasForeignKey<ValuationResult>("ValuationId") .IsRequired(); } }
第三步:删除派生类中的重复关联配置
删掉ScoringCardValuationMapping和FirstChicagoValuationMapping中HasOne(c => c.Result).WithOne()相关的配置代码,避免覆盖基类配置。
效果验证
执行添加迁移操作后,ValuationResult表仅会生成一个名为ValuationId的外键,最终保留两张TPH表,完全符合预期。业务层面可以通过泛型约束和ValuationType枚举保证Valuation派生类和Result派生类的对应关系,不会出现类型不匹配的关联。
内容的提问来源于stack exchange,提问作者ali lotfi
相关产品推荐
相关产品推荐

