Search code examples
asp.net-mvcef-code-firstcascading-deletes

How can I specify null to foreign keys on parent delete at once in M-V-C Code first approach?


I have many tables which have foreign key relations. Such as Countries and Cities relationship. When I am deleting the country my application is breaking down because I have foreign key relationship. What I want is if user deletes the country, it should get deleted and set forrign keys to null. Following is my code in OnModelCreating Method:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Player>().HasOptional(r => r.Team)
        .WithMany(a => a.Players)
        .HasForeignKey(b => new { b.TeamId })
        .WillCascadeOnDelete(false);

    base.OnModelCreating(modelBuilder);
}

Problem here is I have 20 to 25 tables I don't want to do it manually. Is there any code which will automatically set cascade false for entire applciation?


Solution

  • Yes, you can remove the cascade delete for One-to-many and/or Many-to-many conventions in Code First. Just add either or both of these to your OnModelCreating:

    modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
    modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
    

    This will disable it, but you can turn cascade delete back on with .WillCascadeOnDelete(true) as needed. See here and here.

    EDIT: If your question is about setting FK to null for a collection, you could do this:

    1. Make sure you have a collection of cities on the country.
    2. Expose CountryId as a FK on your City model and make it nullable.
    3. Set them to null and delete the country.
    var countryToDelete =  context.Country.Include(c => c.Cities).FirstOrDefault(c => c.CountryId == countryIdToDelete;
    countryToDelete.Cities.ForEach(c => c.CountryId = null);
    context.Country.Remove(countryToDelete);
    context.SaveChanges();