实体框架,外键约束可能会导致循环或多个级联路径

本文关键字:循环 路径 级联 框架 约束 实体 | 更新日期: 2023-09-27 18:36:16

我首先在我的项目中使用实体代码。基本上我有3个班级UsersBranchsUsersBranchs

Users包含UserIDName ,...

Branchs包含BranchIDLocation、... 和用户ID,指的是分支的创建者UsersBranchs只有两列分支ID和用户ID,用于定义哪个用户在哪个分支中

问题是我收到此错误:

"FK_dbo。UsersBranchs_dbo。表"用户分支"上的Users_UsersID"可以 导致周期或多个级联路径。指定"删除时不执行任何操作"或 在更新时不执行任何操作,或修改其他外键约束。

你能帮我吗?

更新
它是用户分支类

[ForeignKey("UserID")]
public CoreUsers User { get; set; }
public Guid UsersID { get; set; }
[ForeignKey("BranchID")]
public Branchs Branch { get; set; }
public Guid BranchID { get; set; }


并将此行添加到 DbContext 类中,以同时使用 UserID 和 BranchID 作为键

modelBuilder.Entity().HasKey(x => new { x.UserID, x.BranchID });


分支类是

   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   [Key]
   public Guid ID { get; set; }
   [ForeignKey("UserID")]
   public CoreUsers User { get; set; }
   public Guid UserID { get; set; }
   public .....


用户类为

   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   [Key]
   public Guid ID { get; set; }
   public .....

实体框架,外键约束可能会导致循环或多个级联路径

长期以来,

无法处理多个级联路径和级联删除到同一个表一直是 Sql Server 的限制。只需谷歌错误消息。基本上,如果要使用级联删除,则必须确保只有一个级联路径。

目前,您有两条路径来自分支 -> UsersBranchs 和分支 -> 用户 -> UsersBranchs。

默认情况下,EF 设置级联删除,但可以通过删除 DbContext 中的约定来停止。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // Manually set cascade delete behaviour
    modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
    modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
    base.OnModelCreating(modelBuilder);
}

然后,您必须在您想要级联删除的任何关系上设置 WillCascadeOnDelete(true)。请参阅实体框架文档。

除此之外,您的模型似乎有点奇怪。您看起来像是在尝试制作一个多对多链接/连接表,UsersBranchs,但是您在分支上也只有一个用户,这实际上没有意义。在这种情况下,您甚至需要 UsersBranchs 表吗?您的意思是在您的分支上有一个用户集合,即导航属性而不是外键,它提供了一对多关系分支 ->用户?

顺便说一句,我真的很不喜欢对单个实体使用复数形式。

我认为您遇到了问题,因为您没有告诉实体框架它将如何在级联删除时处理这些类

在 DbContext 类中,重写 OnModelCreating 方法并编写此代码

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{    
     modelBuilder.Entity<UserBranch>()
         .HasRequired(t => t.CoreUsers)
         .WithMany()
         .HasForeignKey(t => t.UserID)
         .WillCascadeOnDelete(false);
     modelBuilder.Entity<UserBranch>()
         .HasRequired(t => t.Branch)
         .WithMany()
         .HasForeignKey(t => t.BranchID)
         .WillCascadeOnDelete(false);
     modelBuilder.Entity<Branch>()
         .HasRequired(t => t.User)
         .WithMany()
         .HasForeignKey(t => t.UserID)
         .WillCascadeOnDelete(false);
}

希望这对你有帮助