简体   繁体   中英

Entity Framework, Foreign key constraint may cause cycles or multiple cascade paths

I use Entity Code first for my project. Basically I have 3 class Users , Branchs and UsersBranchs .

Users contains UserID , Name ,...

Branchs contains BranchID , Location , ... and UserID which is refer to creator of branch and UsersBranchs just have have two column BranchID and UserID which is define which user is in which branch

the problem is I get this error:

'FK_dbo.UsersBranchs_dbo.Users_UsersID' on table 'UsersBranchs' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

Can you help me please?

Update
It's 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; }


And also add this line to DbContext class to use both UserID and BranchID as key

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


Branchs Class is

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

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

   public .....


Users Class is

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

   public .....

Not being able to handle multiple cascade paths and cascade delete to same table has been a limitation of Sql Server for a long time. Just Google the error message. Basically, if you want to use cascade delete then you'll have to make sure that there is only a single cascade path.

At the moment you have two paths from Branchs -> UsersBranchs and Branchs -> Users -> UsersBranchs.

EF by default sets cascade delete but it may be stopped by removing the conventions in your DbContext.

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

    base.OnModelCreating(modelBuilder);
}

Then you'll have to set WillCascadeOnDelete(true) on any relationships where you want cascade delete. See the Entity Framework documentation .

Other than that your model seems a bit strange. You look like you're trying to make a many-to-many link/join table, UsersBranchs, but you also have a single User on the Branchs which doesn't really make sense. Do you even need the UsersBranchs table in that case? Did you mean to have a collection of Users on your Branchs, ie a navigation property rather than a foreign key, which gives a one-to-many relationship Branchs -> Users?

As an aside I really dislike using plurals for single entities.

I think you are getting the problem because you didn't tell Entity framework how it will treat these classes on delete on cascade

in your DbContext class, override the OnModelCreating method and write this code

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);
}

hope this will help you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM