Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cascade deleting with EF Core

I am having a few issues with EF Core at the moment. I have some data that I need to delete, and I am struggeling to see how the fluent API works, exactly in regards to the .OnDelete() function.

Considering the classic blog/post scenario from microsofts own websites, I wonder what entity, exactly the OnDelete() is 'targeting' (for the lack of a better word) In some instances it seems to be the blog, in others, the post. Can the Cascade delete be defined from both sides (that the posts are deleted when the parent Blog is) if so i imagine the code should look like this:

model.Entity<Post>().HasOne(p => p.Blog).WithMany(b => b.Posts).HasForeignKey(p => p.BlogId).OnDelete(DeleteBehavior.Cascade)

As i understand this is saying "When a Blog is deleted, first delete all posts referencing this blog" meaning the OnDelete(DeleteBehavior.Cascade)applies to blog, not to post.

But is this the same then?

model.Entity<Blog>().HasMany(b => b.Posts).WithOne(p => p.Blog).OnDelete(DeleteBehavior.Cascade)

or does OnDelete(DeleteBehavior.Cascade) apply to Post rather than blog?

like image 853
rasmus91 Avatar asked Feb 08 '18 18:02

rasmus91


People also ask

How do I enable cascade delete in Entity Framework?

Cascade delete automatically deletes dependent records or sets null to ForeignKey columns when the parent record is deleted in the database. Cascade delete is enabled by default in Entity Framework for all types of relationships such as one-to-one, one-to-many and many-to-many.

When should I delete cascade?

Use the ON DELETE CASCADE option to specify whether you want rows deleted in a child table when corresponding rows are deleted in the parent table. If you do not specify cascading deletes, the default behavior of the database server prevents you from deleting data in a table if other tables reference it.

What is cascaded deletion?

A foreign key with cascade delete means that if a record in the parent table is deleted, then the corresponding records in the child table will automatically be deleted. This is called a cascade delete in SQL Server.

Is Cascade delete good practice?

On delete cascade is a particularly bad thing to use to clean data because it doesn't discriminate against the data you want the FK to stop the delete for and the data you are trying to completely purge.


1 Answers

Cascade delete always works in one direction - from principal entity to dependent entity, i.e. deleting the principal entity deletes the dependent entities. And for one-to- many relationships the one side is always the principal and the many side is the dependent.

Looks like you are confused by the fluent configuration. Note that each relationship consists of two ends. The fluent configuration allows you to start with one of the ends and relate it to the other end, or vice versa, but still you are configuring (defining) a single relationship. So

Entity<A>().HasOne(a => a.B).WithMany(b => b.As) 

is the same as

Entity<B>().HasMany(b => b.As).WithOne(a => a.B); 

and they both define one and the same relationship. Which one you choose doesn't matter, just use single configuration per relationship in order to avoid discrepancies.

With that being said,

model.Entity<Post>().HasOne(p => p.Blog).WithMany(b => b.Posts)     .HasForeignKey(p => p.BlogId)     .OnDelete(DeleteBehavior.Cascade); 

and

model.Entity<Blog>().HasMany(b => b.Posts).WithOne(p => p.Blog)     .HasForeignKey(p => p.BlogId)     .OnDelete(DeleteBehavior.Cascade); 

is one and the same and define single one-to-many relationship from Blog to Post. Since Blog is the one side and Post is the many side, the Blog is the principal entity and the Post is the dependent entity, hence deleting a Blog will delete the related Posts.

Reference:

  • Relationships - Definition of terms
  • Cascade Delete
like image 93
Ivan Stoev Avatar answered Oct 21 '22 18:10

Ivan Stoev