EF Core .NET 5 Code First 同实体多关联配置报错问题咨询
EF Core多关联指向同表配置错误解决方案
错误原因
当前配置将4个不同关联绑定到了CompanyAddress表的同一个CompanyId字段:1个一对多关联(Company.Addresses → CompanyAddress.Company) + 3个一对一默认地址关联,EF Core无法区分同一外键对应的关联规则,因此抛出无法识别导航属性的异常。
调整步骤
1. 扩展Company实体,新增默认地址外键字段
在Company类中添加三个可空外键属性,用于存储三个默认地址的主键Id:
public class Company : AbstractValidatableEntity { public string Name { get; set; } public List<User> Users { get; set; } public Guid OwnerId { get; set; } public User Owner { get; set; } public List<CompanyAddress> Addresses { get; set; } // 新增三个默认地址外键 public Guid? DefaultAddressId { get; set; } public Guid? DefaultBillingAddressId { get; set; } public Guid? DefaultDeliveryAddressId { get; set; } // 原有导航属性保留 public CompanyAddress DefaultAddress { get; set; } public CompanyAddress DefaultBillingAddress { get; set; } public CompanyAddress DefaultDeliveryAddress { get; set; } }
2. 修改Fluent API关联配置
将三个一对一关联的外键从CompanyAddress表调整到Company表,和一对多关联的外键完全隔离,避免冲突:
public class CompanyConfiguration : AbstractEntityConfiguration<Company> { public override void Configure(EntityTypeBuilder<Company> builder) { base.Configure(builder); builder.ToTable("Companies"); builder.Property(s => s.Name) .IsRequired(true) .HasMaxLength(255); // 原有用户关联不变 builder.HasMany(s => s.Users) .WithOne(u => u.Company) .HasForeignKey(u => u.CompanyId) .IsRequired(false) .HasConstraintName("FK_COMPANY_USERS"); // 原有地址一对多关联不变 builder.HasMany(s => s.Addresses) .WithOne(a => a.Company) .HasForeignKey(a => a.CompanyId) .IsRequired() .HasConstraintName("FK_COMPANY_ADDRESSES") .OnDelete(DeleteBehavior.Cascade); // 修改默认地址关联:外键存放在Company表 builder.HasOne(s => s.DefaultAddress) .WithOne() .HasForeignKey<Company>(c => c.DefaultAddressId) .IsRequired(false) .HasConstraintName("FK_COMPANY_DEFAULT_ADDRESS") .OnDelete(DeleteBehavior.Restrict); // 修改默认账单地址关联 builder.HasOne(s => s.DefaultBillingAddress) .WithOne() .HasForeignKey<Company>(c => c.DefaultBillingAddressId) .IsRequired(false) .HasConstraintName("FK_COMPANY_DEFAULT_BILLING_ADDRESS") .OnDelete(DeleteBehavior.Restrict); // 修改默认收货地址关联 builder.HasOne(s => s.DefaultDeliveryAddress) .WithOne() .HasForeignKey<Company>(c => c.DefaultDeliveryAddressId) .IsRequired(false) .HasConstraintName("FK_COMPANY_DEFAULT_DELIVERY_ADDRESS") .OnDelete(DeleteBehavior.Restrict); builder.HasIndex(s => s.Name) .HasDatabaseName("IX_COMPANY_NAME"); } }
效果说明
调整后生成的数据库结构完全符合业务需求:
CompanyAddress表仅保留CompanyId字段,关联所属公司,支持一家公司存储多个地址Companies表新增DefaultAddressId、DefaultBillingAddressId、DefaultDeliveryAddressId三个外键字段,分别指向对应类型的默认地址- 四类关联完全独立,不会出现识别冲突,同时避免了多关联指向同外键产生的级联删除循环问题
内容的提问来源于stack exchange,提问作者Paullus Nava
相关产品推荐
相关产品推荐

