skip to Main Content

I want to create a relationship between the menu items and the restaurant – each menu item can have one restaurant and the restaurant can have multiple menu items, I would like to set this up in a one-to-many relationship, but after the ‘update-database’ command I get an error:

Introducing FOREIGN KEY constraint ‘FK_MenuItems_Restaurants_RestaurantId’ on table ‘MenuItems’ 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 or index. See previous errors.

Any tips how to fix that?

public class Restaurant
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public string Description { get; set; } = string.Empty;
    public string Address { get; set; } = string.Empty;
    public string PhoneNumber { get; set; } = string.Empty;

    public List<MenuItem> MenuItems { get; set; } = new List<MenuItem>();
}

public class MenuItem
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public string Description { get; set; } = string.Empty;
    public Restaurant Restaurant { get; set; }
    public int RestaurantId { get; set; }
}

And I configure it like this in my DbContext class:

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

    modelBuilder.Entity<Restaurant>()
            .HasOne(k => k.Owner)
            .WithMany(k => k.Restaurants)
            .HasForeignKey(k => k.OwnerId)
            .OnDelete(DeleteBehavior.Cascade);

    modelBuilder.Entity<MenuItem>()
            .HasOne(k => k.Restaurant)
            .WithMany(k => k.MenuItems)
            .HasForeignKey(k => k.RestaurantId)
            .OnDelete(DeleteBehavior.NoAction);

    modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}

2

Answers


  1. I would remove HasOne and replace it with HasRequired and map it’s Id. Entity will make Foreign key on it’s own.

    protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
    
            modelBuilder.Entity<Restaurant>()
                .HasRequired(k => k.Owner)
                .WithMany(k => k.Restaurants)
                .Map(k => k.MapKey("OwnerId"))
                .OnDelete(DeleteBehavior.Cascade);
    
            modelBuilder.Entity<MenuItem>()
                .HasRequired(k => k.Restaurant)
                .WithMany(k => k.MenuItems)
                .Map(k => k.MapKey("RestaurantId"))
                .OnDelete(DeleteBehavior.NoAction);
    
    
            modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
    
        }
    
    Login or Signup to reply.
  2. I think the issue arises from the combination of cascade delete actions on the Restaurant entity and the MenuItem entity. To fix this issue, you should adjust the cascade delete behavior for one or both of your relationships.

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    
        modelBuilder.Entity<Restaurant>()
            .HasOne(k => k.Owner)
            .WithMany(k => k.Restaurants)
            .HasForeignKey(k => k.OwnerId)
            .OnDelete(DeleteBehavior.Cascade);
    
        modelBuilder.Entity<MenuItem>()
            .HasOne(k => k.Restaurant)
            .WithMany(k => k.MenuItems)
            .HasForeignKey(k => k.RestaurantId)
            .OnDelete(DeleteBehavior.Restrict); // Change this to Restrict
    
        modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search