EF Core 8迁移EF6 TPH模型时派生类型外键报错求助
解决EF Core 8迁移中的TPH继承属性错误
错误原因
EF Core的表继承(TPH)处理逻辑与EF6存在差异:当多个子类(AccountTarget、PortfolioTarget)将专属属性映射到同一数据库列(OwnerID)时,EF Core会尝试将这些子类属性提升到父类Target中,但父类并未声明这些属性,从而触发该错误。
修改方案
通过Fluent API显式为每个子类配置专属属性的列映射,避免EF Core自动提升属性到父类:
1. 更新OnModelCreating方法
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 父类Target基础配置 modelBuilder.Entity<Target>(entity => { entity.ToTable("Targets") .HasDiscriminator<char>("OwnerType") .HasValue<PortfolioTarget>('P') .HasValue<AccountTarget>('A'); entity.Property(e => e.TargetID).ValueGeneratedNever(); entity.Property(e => e.RowVersion) .IsRowVersion() .IsConcurrencyToken(); }); // 显式配置AccountTarget的属性映射 modelBuilder.Entity<AccountTarget>(entity => { entity.Property(e => e.AccountID).HasColumnName("OwnerID"); entity.Property(e => e.InvestmentID).HasColumnName("BalanceOwnerID"); }); // 显式配置PortfolioTarget的属性映射 modelBuilder.Entity<PortfolioTarget>(entity => { entity.Property(e => e.PortfolioID).HasColumnName("OwnerID"); entity.Property(e => e.InvestmentID).HasColumnName("BalanceOwnerID"); }); }
2. 可选:统一属性配置方式(移除特性避免冲突)
如果选择使用Fluent API配置,可移除子类中的[Column]特性,保持配置一致性:
// 修改AccountTarget类 public partial class AccountTarget : Target { Guid _AccountID; public virtual Guid AccountID { get; set; } Guid _InvestmentID; public virtual Guid InvestmentID { get; set; } // 关联属性保留不变 [ForeignKey(nameof(AccountID))] [InverseProperty("AccountTargets")] public virtual Account Account { get; set; } [ForeignKey(nameof(InvestmentID))] [InverseProperty("AccountTargets")] public virtual Investment Investment { get; set; } } // PortfolioTarget类做同样修改,移除[Column]特性
原理说明
EF Core要求TPH模式下的子类专属属性必须显式声明其列映射,通过Fluent API单独配置每个子类的属性,明确告知EF Core这些属性属于子类而非父类,从而避免错误的属性提升操作,与EF6 EDMX的自动映射逻辑对齐。
内容的提问来源于stack exchange,提问作者Randall Doser
相关产品推荐
相关产品推荐

