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

时间:2015-01-06 04:33:59

标签: c# .net sql-server entity-framework

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

Users包含UserIDName,...

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

问题是我收到此错误:

  表'UsersBranchs'上的'pK_dbo.UsersBranchs_dbo.Users_UsersID'可以   导致循环或多个级联路径。指定ON DELETE NO ACTION或   ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。

你能帮我吗?

更新
这是UsersBranchs Class

[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<UsersBranchs>().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 .....

2 个答案:

答案 0 :(得分:1)

无法handle multiple cascade pathscascade delete to same table长期以来一直是Sql Server的限制。只是谷歌的错误信息。基本上,如果你想使用级联删除,那么你必须确保只有一个级联路径。

目前你有两条路径分支 - &gt; UsersBranchs and Branchs - &gt;用户 - &gt; 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)。请参阅Entity Framework documentation

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

另外,我真的不喜欢将复数用于单个实体。

答案 1 :(得分:1)

我认为你遇到了这个问题,因为你没有告诉实体框架它如何在级联上删除这些类

在您的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);
}

希望这会对你有所帮助