Entity Framework (Core) - cascading delete
For ef core 3 you do not need anythink in "WithOne"
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasMany(e => e.Posts)
.WithOne()
.OnDelete(DeleteBehavior.ClientCascade);
}
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);
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;
}
Thanks for the comments/posts.
My EF model classes and configuration are correct. The issue is my schema has places where multiple cascade paths exist, which ok because the primary item in those paths are never deleted (soft-deleted). While EF does not have an issue with multiple cascade paths, SQL sure does, and SQL throws errors when trying to update the database.
I didn't want disable cascade deletes and set up elaborate cascading functionality in code, just because of a couple places where multiple cascade paths exist.
However, the problem is I wasn't thinking about this correctly. All I really have to do is disable cascading on the FKs that cause the multiple paths, and leave it enabled for the rest. I think I was just burnt out when I asked this question. :)