Specify ON DELETE NO ACTION in ASP.NET MVC 4 C# Code First

48,649

Solution 1

You can either disable it for your entire context by removing the cascade delete convention in the OnModelCreating method:

  protected override void OnModelCreating( DbModelBuilder modelBuilder )
  {
     modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
  }

or, you can do it per relationship using a fluent mapping (also in the OnModelCreating):

EDIT: you would put it in your menu entities

public class MenuEntities : DbContext
{
    public DbSet<Status> Statuses { get; set; }
    public DbSet<Restaurant> Restaurants { get; set; }
    public DbSet<Menu> Menus { get; set; }

      protected override void OnModelCreating( DbModelBuilder modelBuilder )
      {

         modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

     modelBuilder.Entity<Menu>()
        .HasRequired( f => f.Status )
        .WithRequiredDependent()
        .WillCascadeOnDelete( false );

     modelBuilder.Entity<Restaurant>()
        .HasRequired( f => f.Status )
        .WithRequiredDependent()
        .WillCascadeOnDelete( false );

      }

}

Solution 2

Just make the FK property nullable, then the cascade delete will be gone.

public int? StatusId { get; set; }

Solution 3

add this line to end of the field in the context;

.OnDelete(DeleteBehavior.Restrict);

Solution 4

After making the changes to the model, make sure you regenerate the migration file by adding the -Force parameter.

Add-Migration MigrationName -Force

Share:
48,649
Gravy
Author by

Gravy

Updated on September 25, 2020

Comments

  • Gravy
    Gravy over 3 years

    How do I specify ON DELETE NO ACTION Foreign Key Constraint in my model designs?

    At present, I have:

    public class Status
    {
        [Required]
        public int StatusId { get; set; }
    
        [Required]
        [DisplayName("Status")]
        public string Name { get; set; }
    }
    
    public class Restuarant
    {
        public int RestaurantId { get; set; }
        [Required]
        public string Name { get; set; }
        [Required]
        [EmailAddress]
        public string Email { get; set; }
        [Required]
        public string Telephone { get; set; }
        [Required]
        public int StatusId { get; set; }
        public List<Menu> Menus { get; set; }
    
        // NAVIGATION PROPERTIES
        public virtual Status Status { get; set; }
    }
    
    public class Menu
    {
        public int MenuId { get; set; }
    
        [Required]
        public int RestaurantId { get; set; }
    
        [Required]
        public string Name { get; set; }
    
        [Required]
        public int StatusId { get; set; }
    
        // NAVIGATION PROPERTIES
        public virtual Status Status { get; set; }
        public virtual Restaurant Restaurant { get; set; }
    }
    

    And my DbContext:

    public class MenuEntities : DbContext
    {
        public DbSet<Status> Statuses { get; set; }
        public DbSet<Restaurant> Restaurants { get; set; }
        public DbSet<Menu> Menus { get; set; }
    }
    

    As you can see:

    • a Restaurant has many menus
    • a Restaurant has one status
    • a Menu belongs to 1 restaurant
    • Both Restaurants and Menus have 1 status. (Live, Invisible, Draft)

    Naturally, if a status is deleted, I certainly don't want to cascade as this will muck everything up.

    UPDATE:

    Mark Oreta mentions using the following in his example below:

    modelBuilder.Entity<FirstEntity>() 
        .HasMany(f => f.SecondEntities) 
        .WithOptional() 
        .WillCascadeOnDelete(false); 
    

    Where do I put this code? Within my MenuEntities / DbContext class? Can anybody provide an example of this being used?

    UPDATE: Got this bit working now, however this has created a multiplicity constraint error when trying to seed the DB...

    Multiplicity constraint violated. The role 'Menu_Status_Source' of the relationship 'LaCascadaWebApi.Models.Menu_Status' has multiplicity 1 or 0..1.
    

    My Database Initialiser:

    http://pastebin.com/T2XWsAqk