Entity Framework (Core) - cascading delete

11,151

Solution 1

Actually EF Core 3.0 is the first version of EF which adds such capability via DeleteBehavior.ClientCascade option (unfortunately not yet included in the Cascade Delete section of the documentation):

For entities being tracked by the DbContext, dependent entities will deleted when the related principal is deleted.

If the database has been created from the model using Entity Framework Migrations or the EnsureCreated() method, then the behavior in the database is to generate an error if a foreign key constraint is violated.

Shortly, all Client* delete behaviors are mapped to Restrict, i.e. enforced FK relationship in database without cascade. Client behavior apply only on entities tracked by the context, so make sure you Include the related data before deleting (as in your sample).

To configure the option, you'd need fluent API at minimum having valid Has + With in order to get to OnDelete method, e.g.

modelBuilder.Entity<Blog>()
    .HasMany(e => e.Posts)
    .WithOne(e => e.Blog)
    .OnDelete(DeleteBehavior.ClientCascade); 

Solution 2

You can add the Cascade Behavior to your entities as below. inside OnModelCreating;

foreach (var foreignKey in builder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
            {
                foreignKey.DeleteBehavior = DeleteBehavior.Cascade;
            }

enter image description here

Share:
11,151

Related videos on Youtube

J. Lee
Author by

J. Lee

Updated on September 14, 2022

Comments

  • J. Lee
    J. Lee over 1 year

    I’m using EF Core 3.1.1, but I believe this question applies to all versions of EF.

    It seems the EF has the ability to cascade delete - if it is enabled, and if the dependent objects are loaded in the context.

    var blog = context.blogs.Include(x => x.Posts).First(x => x.BlogId == id);
    context.blogs.Remove(blog);
    

    The above statement deletes all the blog’s posts, and then the blog - each with a different sql statement.

    This is what I want, however when using code-first, it also creates the tables with cascading delete enabled in the database. (ON DELETE CASCADE)

    Can you enable cascade delete in EF, and rely of EF deleting dependent objects, without also enabling database level cascade delete? (Or am I understanding this incorrectly?)

    The reason is migrations fail because SQL won’t enable cascade delete in the database because it detects multiple cascade paths (even though multiple wouldn’t occur naturally in the schema)

    Thanks!

    • J. Lee
      J. Lee over 4 years
      @Dennis1679 - I have read in multiple places that if dependent objects are loaded in the db context, EF will delete them by executing sql statements before it deletes the object. And if the dependent objects are not loaded, it relies on the database to cascade. Is this not true? Perhaps its only true in EF core? Also, models are set up correctly (I will post below) - this is more of a general question.
  • J. Lee
    J. Lee over 4 years
    Thanks Ivan - thats exactly what I was looking for!
  • Akbar Asghari
    Akbar Asghari over 4 years
    oh sorry for my answer i delete it now thanks for say me
  • Ivan Stoev
    Ivan Stoev over 3 years
    @yogihosting It works. Read the answer carefully and the documentation links. In your case the cascade delete is from Country to City, not vice versa as you seem to think.
  • yogihosting
    yogihosting over 3 years
    Thank you @IvanStoev I understood and able to sort out my code. I checked and found out the Include is not needed nor ClientCascade in 3.1 EF version. DeleteBehavior.Cascade is working in my case and I am also not including related entities with include.