Deleted entities show up as modified in Entity Framework Core's ChangeTracker

entity-framework entity-framework-core

Question

I'm trying to understand why Entity Framework Core 2's ChangeTracker sets the state of deleted entities to 'modified' if the deletion is done by removing the entity from a list in another entity.

Consider this example:

Class1
  List<Class2> MyListOfClass2Objects

Class2

Both classes have their own DbSet in EF's DbContext. If I remove an object from the MyListOfClass2Objects list and then call DbContext.SaveChanges(), the state of the Class2 object in ChangeTracker is set to EntityState.Modified, and not EntityState.Deleted, which I would expect. If I delete the entity by calling Set<T>.Remove() the state in the ChangeTracker is EntityState.Deleted. In both cases however, the entity is removed from the database.

So, why does Entity Framework set different values in ChangeTracker depending on how you delete an entity even though it is really deleted in both cases?

1
5
3/25/2018 6:03:57 PM

Accepted Answer

Update: At the end (thanks to @Sebastian finding) it turns out to be a known issue with the current (at the time of writing) EF Core implementation, tracked originally by EF Core marks entities removed From child collections as modified #10093. The short explanation is:

because cascade deletes happens while SaveChanges is running which means in your code will not see this state as it looks at the state before SaveChanges has executed

and

Cascade delete happens as part of SaveChanges.

Fixup of non-deleted entities to no longer reference deleted entities happens after SaveChanges.

The currently associated action item is Allow delete fixup and cascade timing to be configured #10114, unfortunately in backlog, i.e. unknown if and when will be addressed.

Original:

Because when you remove an entity from the corresponding DbSet, you are telling EF that you want to delete it. But when you remove it from the parent entity collection, if the relationship is optinal (as it seems to be in your case), EF treats that as attempt to disassociate the child from the parent (same as setting child.Parent to null), hence it sets the FK and parent navgigation property to null and marks the entity as Modified. If you really want to delete it, you should use the first method.

All this is explained in the Removing relationships section of the documentation:

You can remove a relationship by setting a reference navigation to null, or removing the related entity from a collection navigation.

Removing a relationship can have side effects on the dependent entity, according to the cascade delete behavior configured in the relationship.

By default, for required relationships, a cascade delete behavior is configured and the child/dependent entity will be deleted from the database. For optional relationships, cascade delete is not configured by default, but the foreign key property will be set to null.

5
3/27/2018 7:15:35 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow