简体   繁体   中英

Database Causing “Cycles” or “Multiple Cascade Paths”

I'm using ASP.NET MVC 4 Entity Framework 5 to generate a code first migration for a database structure of the below classes that have relationships between them. However I've encountered a problem where it's causing this error whenever I try to update my database from the migration:

Paste Bin of the migration file can be found here: http://pastebin.com/ngXacrKV

Error returned:

Introducing FOREIGN KEY constraint 'FK_dbo.Bookings_dbo.Rooms_RoomId' on table 'Bookings' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint. See previous errors.

Bunk.cs

public class Bunk
{
    [Key]
    public int BunkId { get; set; }

    public BunkStatus BunkStatus { get; set; }

    [ForeignKey("Room")]
    public int RoomId { get; set; }
    public virtual Room Room { get; set; }

    // Added for convenience
    public virtual ICollection<Booking> Bookings { get; set; }
}

Room.cs

public class Room
{
    [Key]
    public int RoomId { get; set; }

    public string RoomName { get; set; }

    public Gender RoomGender { get; set; }

    public RoomStatus RoomStatus { get; set; }

    public virtual ICollection<Bunk> Bunks { get; set; }

    // Added for convenience
    public virtual ICollection<Booking> Bookings { get; set; }

}

Bookings.cs

public class Booking
{
    [Key]
    public int BookingId { get; set; }

    //[ForeignKey("UserProfile")]
    //public int UserProfileId { get; set; }
    //public UserProfile UserProfile { get; set; }

    [ForeignKey("Bunk")]
    public int BunkId { get; set; }
    public Bunk Bunk { get; set; }

    public int Duration { get; set; }

    [ForeignKey("Preferred_Room")]
    public int RoomId { get; set; }
    public Room Preferred_Room { get; set; }

    public Decimal Price { get; set; }

    public BookingStatus BookingStatus { get; set; }
}

What would the best work around be to remove this issue without causing too much disturbance to the original class structure. I'm not too worried about adding new joining tables as long as I can still access the code in a Lazy loading way in my controllers/view models.

you can try to specify Fluent API to set no cascade delete

 public class YOURContext: DbContext{

 protected override void OnModelCreating(DbModelBuilder modelBuilder) {
 // here is where fluent API goes.
 // I suspected the error is EF wanting a NO cascade delete. Hence the suggestion to try

 entity<Booking>.HasOptional(t => t.Bunk) 
              .WithOptionalPrincipal()
              .WillCascadeOnDelete(false);      // <<<<<< this is the option to try.

 // you may also need to try the same with Preferred_Room as well.

If no cascade delete is required then in Database context class we can set cascade delete to false for all the relationships by overriding OnModelCreating method as given below. Default EF makes it cascade delete that is why you are getting exception of cycles or multiple delete path.

 public class MyContext: DbContext
 {
    //db sets defined


    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);            

        modelBuilder.Entity<PrimaryKeyTable>().HasMany(x => x.ChildTableCollection).WithRequired(x => 
        Key).WillCascadeOnDelete(false);

        //In your case

         modelBuilder.Entity<Bunk>().HasMany(x => x.Bookings).WithRequired(x => 
         x.BunkId).WillCascadeOnDelete(false);

        // same for room if required.
    }
}

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