EF Core 5如何实现三方关联关系并解决外键级联路径报错问题
报错原因
这个错误是SQL Server的原生限制,和EF能否实现三方关联无关:你的Contract表存在两个指向User表的外键(ConsultantId、ManagerId),EF默认给外键开启级联删除,此时删除一个User记录时,会触发两条级联删除路径(删除该用户作为顾问的所有合同、删除该用户作为经理的所有合同),SQL Server不允许存在多重级联删除路径,因此抛出该错误。
修复方案
不需要调整整体模型结构,仅需做两处修改即可:
1. 拆分User实体的导航属性(可选,推荐)
你当前User实体仅定义了一个Contracts集合,无法区分合同是该用户作为顾问参与的,还是作为经理监管的,建议拆分为两个导航属性,后续查询更方便:
public class User { public int UserId { get; set; } public string UserName { get; set; } public string LastName { get; set; } public string FirstName { get; set; } public string Email { get; set; } public UserStatus Status { get; set; } // Manager or user // 拆分两个导航属性 public ICollection<Contract> ConsultantContracts { get; set; } public ICollection<Contract> ManagerContracts { get; set; } }
2. 关闭其中一个或两个User外键的级联删除
在OnModelCreating方法中,给指向User的外键配置关闭级联删除即可,示例配置如下:
protected override void OnModelCreating( ModelBuilder modelBuilder ) { modelBuilder.Entity<Contract>() .HasOne( c => c.Consultant ) .WithMany( u => u.ConsultantContracts ) // 关闭级联删除 .OnDelete(DeleteBehavior.NoAction); modelBuilder.Entity<Contract>() .HasOne( c => c.Manager ) .WithMany( m => m.ManagerContracts ) // 也可根据业务需求选择DeleteBehavior.Restrict,和NoAction的区别是约束检查时机不同 .OnDelete(DeleteBehavior.NoAction); modelBuilder.Entity<Contract>() .HasOne( c => c.Customer ) .WithMany( e => e.Contracts ); }
如果不想拆分导航属性,也可以直接把两个WithMany的参数留空,仅保留OnDelete配置,同样可以解决报错,只是后续导航查询会不够方便。
修改完成后重新执行Add-Migration和Update-Database即可正常生成表结构。
内容的提问来源于stack exchange,提问作者ihadjiat
相关产品推荐
相关产品推荐

