Entity Framework Cascade Delete For Inherited class

丶灬走出姿态 提交于 2019-12-05 13:42:01
Gert Arnold

This has been reported and discussed more often, for example here: Cascade delete in entity framework ( table per type inheritance ). I would mark this as a duplicate, but since the question and Slauma's answer are about EF version 4, I think it's time for an update.

The discouraging part is that the bug (which I think it is) still occurs. I may be overlooking some edge cases (I probably do), but I think in TPT the relation between base and subtype could default to cascaded delete.

The error as indicated in the referred question still occurs. In your case you would see it if you'd delete a master entity that owns a collection of properties. Let's say you have this class:

class Master
{
    public int ID { get; set; }
    public virtual ICollection<PropertyBase> Properties { get; set; }
}

And the association Properties is marked as cascaded delete.

Now if you do ...

var master = context.Find(x);
context.Masters.Remove(master);
context.SaveChanges();

... you'll see that EF only emits one DELETE statement for Master. It relies on the database to cascade the delete to the Properties table. Well, it does, but then the FKs from IntProperty and TextProperty are violated, because these do not cascade deletes.

You can fix this by doing:

var master = context.Include(m => m.Properties).Single(m => m.ID == x);
context.Masters.Remove(master);
context.SaveChanges();

Now EF explicitly deletes the properies and the subtypes.1

The funny thing is that EF knows perfectly well that for deleting a property, either by ...

var intProp = context.Properties.OfType<IntProp>().First();
context.Properties.Remove(intProp); // delete from the base table

... or ...

var intProp = context.Properties.OfType<IntProp>().First();
context.IntProperties.Remove(intProp); // delete from the derived table

... it should emit two delete statements.

So that leaves you without tooling to configure the TPT association as cascaded. You'll have to add it to the migration scripts manually. However, that won't stop EF from executing 2 delete statements for each individual property that is to be deleted, because it's not aware of the cascade in the database. This can incur a serious performance hit. But it will enable you to delete a master record (owning properties) by one delete statement.


1 This seems to be an improvement compared to EF 4, where apparently it was necessary to have Remove statements for each child record too.

Cascade deletions can only happens at database level, EF does not do nothing in this regards. The problem here is that you ( and many others :P) are confusing usage of WillCascadeOnDelete. It is useful only when you use Code First development flow, in this case EF will generate migration code to set this property in the database foreign key and nothing more, it is up to the database to delete relationships.

When you work with database first workflow as it seems is your case, this setting is simply ignored.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!