Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow delete fixup and cascade timing to be configured #10114

Closed
ajcvickers opened this issue Oct 18, 2017 · 4 comments · Fixed by #14470
Closed

Allow delete fixup and cascade timing to be configured #10114

ajcvickers opened this issue Oct 18, 2017 · 4 comments · Fixed by #14470

Comments

@ajcvickers
Copy link
Member

@ajcvickers ajcvickers commented Oct 18, 2017

Currently:

  • Cascade delete happens as part of SaveChanges. This prevents cascades happening when all that is intended is a re-parenting.
  • Fixup of non-deleted entities to no longer reference deleted entities happens after SaveChanges. This prevents graph shredding when marking entities as deleted.

However, there are scenarios where it is useful for these things to happen at different times:

  • In a data-binding app, cascade delete should probably happen immediately so that the view of the data correlates to what will happen when SaveChanges is called.
    • Similarly, it can be useful to have the fixup to the deleted entities happen
  • When attempting audit state before or in SaveChanges, it is useful to know what will be deleted beforehand.

There are a few things we could do:

  • Add a "PerformCascades" method to the context. This would run cascade delete code when called.
  • Add a context option to make cascading happen immediately on delete
  • Add similar method/option for delete fixup, or have the cascade method/option do the fixup also.
@nehresma

This comment has been minimized.

Copy link

@nehresma nehresma commented Apr 16, 2018

Another use case here: Being able to detect the entities that were removed (possibly by getting a tree of them prior to SaveChanges) so that you can perform an action afterwards. For example, removing referenced objects from the filesystem or S3.

@jonathanford

This comment has been minimized.

Copy link

@jonathanford jonathanford commented Jun 25, 2018

Fixup of non-deleted entities to no longer reference deleted entities happens after SaveChanges. This prevents graph shredding when marking entities as deleted.

Should the same behaviour occur when query filters are applied such as when doing a soft delete? For example in a Blog/Posts scenario, if a Post is soft deleted (using shadow property and query filter), the Post no longer appears in the DbSet, but I still see it in the navigation collection of the Blog.

@johnkwaters

This comment has been minimized.

Copy link

@johnkwaters johnkwaters commented Jan 17, 2019

My 2 cents - my primary interest is in soft delete. I check which entities have been deleted, and instead set an IsDeleted=true and change them to Modified. It would suffice for me to just get some kind of callback where I can do this logic. Since you said the current logic is in order to do the right thing for reparenting, and prevent graph shredding, I don't necessarily want that just undone in the general case. All I need is some point where I get the REAL state of the objects prior to the DB save...

ajcvickers added a commit that referenced this issue Jan 19, 2019
Fixes #10114

Allows timing cascade delete (i.e. delete of dependent on principal deletion) and delete orphans (i.e. delete of dependent on severing its relationship to the principal) to be configured as:
* Immediate: Dependents changed to Deleted immediately, or at least at the next DetectChanges
* OnSaveChanges: Dependents are not changed to Deleted until SaveChanges is called
* Never: Cascades don't happen automatically. They can be triggered by a new method: `context.ChangeTracker.CascadeChanges()`

The default for both has been changed to `Immediate` which is a breaking change, but likely a better default because:
* Auditing in overridden SaveChanges will now report anything that will be deleted
* Data binding will reflect the changes immediately

However, deleting orphans can be more difficult. This doesn't appear to be a major problem in EF Core because we don't aggressively graph shred, we don't typically have entities that handle their own fixup, and conceptual nulls still exist to allow transitionary states.

Note that EF6 does not support deleting orphans, which means the behavior here with both set to Immediate is not quite the same as the default behavior of EF6.
ajcvickers added a commit that referenced this issue Jan 20, 2019
Fixes #10114

Allows timing cascade delete (i.e. delete of dependent on principal deletion) and delete orphans (i.e. delete of dependent on severing its relationship to the principal) to be configured as:
* Immediate: Dependents changed to Deleted immediately, or at least at the next DetectChanges
* OnSaveChanges: Dependents are not changed to Deleted until SaveChanges is called
* Never: Cascades don't happen automatically. They can be triggered by a new method: `context.ChangeTracker.CascadeChanges()`

The default for both has been changed to `Immediate` which is a breaking change, but likely a better default because:
* Auditing in overridden SaveChanges will now report anything that will be deleted
* Data binding will reflect the changes immediately

However, deleting orphans can be more difficult. This doesn't appear to be a major problem in EF Core because we don't aggressively graph shred, we don't typically have entities that handle their own fixup, and conceptual nulls still exist to allow transitionary states.

Note that EF6 does not support deleting orphans, which means the behavior here with both set to Immediate is not quite the same as the default behavior of EF6.
ajcvickers added a commit that referenced this issue Feb 1, 2019
Fixes #10114

Allows timing cascade delete (i.e. delete of dependent on principal deletion) and delete orphans (i.e. delete of dependent on severing its relationship to the principal) to be configured as:
* Immediate: Dependents changed to Deleted immediately, or at least at the next DetectChanges
* OnSaveChanges: Dependents are not changed to Deleted until SaveChanges is called
* Never: Cascades don't happen automatically. They can be triggered by a new method: `context.ChangeTracker.CascadeChanges()`

The default for both has been changed to `Immediate` which is a breaking change, but likely a better default because:
* Auditing in overridden SaveChanges will now report anything that will be deleted
* Data binding will reflect the changes immediately

However, deleting orphans can be more difficult. This doesn't appear to be a major problem in EF Core because we don't aggressively graph shred, we don't typically have entities that handle their own fixup, and conceptual nulls still exist to allow transitionary states.

Note that EF6 does not support deleting orphans, which means the behavior here with both set to Immediate is not quite the same as the default behavior of EF6.
ajcvickers added a commit that referenced this issue Feb 3, 2019
Fixes #10114

Allows timing cascade delete (i.e. delete of dependent on principal deletion) and delete orphans (i.e. delete of dependent on severing its relationship to the principal) to be configured as:
* Immediate: Dependents changed to Deleted immediately, or at least at the next DetectChanges
* OnSaveChanges: Dependents are not changed to Deleted until SaveChanges is called
* Never: Cascades don't happen automatically. They can be triggered by a new method: `context.ChangeTracker.CascadeChanges()`

The default for both has been changed to `Immediate` which is a breaking change, but likely a better default because:
* Auditing in overridden SaveChanges will now report anything that will be deleted
* Data binding will reflect the changes immediately

However, deleting orphans can be more difficult. This doesn't appear to be a major problem in EF Core because we don't aggressively graph shred, we don't typically have entities that handle their own fixup, and conceptual nulls still exist to allow transitionary states.

Note that EF6 does not support deleting orphans, which means the behavior here with both set to Immediate is not quite the same as the default behavior of EF6.
ajcvickers added a commit that referenced this issue Feb 3, 2019
Fixes #10114

Allows timing cascade delete (i.e. delete of dependent on principal deletion) and delete orphans (i.e. delete of dependent on severing its relationship to the principal) to be configured as:
* Immediate: Dependents changed to Deleted immediately, or at least at the next DetectChanges
* OnSaveChanges: Dependents are not changed to Deleted until SaveChanges is called
* Never: Cascades don't happen automatically. They can be triggered by a new method: `context.ChangeTracker.CascadeChanges()`

The default for both has been changed to `Immediate` which is a breaking change, but likely a better default because:
* Auditing in overridden SaveChanges will now report anything that will be deleted
* Data binding will reflect the changes immediately

However, deleting orphans can be more difficult. This doesn't appear to be a major problem in EF Core because we don't aggressively graph shred, we don't typically have entities that handle their own fixup, and conceptual nulls still exist to allow transitionary states.

Note that EF6 does not support deleting orphans, which means the behavior here with both set to Immediate is not quite the same as the default behavior of EF6.
@ajcvickers

This comment has been minimized.

Copy link
Member Author

@ajcvickers ajcvickers commented Feb 6, 2019

Re-opening to ensure breaking change is announced.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.