Entity Framework (Core) - cascading delete
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;
}
Related videos on Youtube
J. Lee
Updated on September 14, 2022Comments
-
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 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 over 4 yearsThanks Ivan - thats exactly what I was looking for!
-
Akbar Asghari over 4 yearsoh sorry for my answer i delete it now thanks for say me
-
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 over 3 yearsThank you @IvanStoev I understood and able to sort out my code. I checked and found out the
Include
is not needed norClientCascade
in 3.1 EF version.DeleteBehavior.Cascade
is working in my case and I am also not including related entities withinclude
.