-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Detaching All Entities After Saving, Gives "Association Has Been Severed" Error #18406
Comments
I do not build any relationships in my OnModelCreating(). I'm using attributes on my entity properties, to define the relationships, only. In OnModelCreating(), I call the following method in an attempt to globally restrict DeleteBehavior:
This does not stop this exception from being thrown. |
Looks like I was able to solve this by making these settings:
This is the suggested fix in the list of breaking changes. I now no longer get an exception when detaching all entities. |
Unfortunately, this has broken something else: Detaching everything after save, now deletes an entity's navigator properties. I really don't want to have to re-retrieve stuff after saving. This isn't in the breaking changes list. Is there any way to mitigate it? |
Duplicate of #17784 The workaround is to use context.ChangeTracker.CascadeDeleteTiming = CascadeTiming.OnSaveChanges;
context.ChangeTracker.DeleteOrphansTiming = CascadeTiming.OnSaveChanges; |
Hi @AndriySvyryd, I found that one out myself as well. But this does not solve the new problem of EF3 nulling navigational properties when detaching all entities. I now have to re-retrieve entities for which I want navigational properties after I've saved & detached them. Can this problem be mitigated as well? Is there already an issue for it, or shall I create one? |
@jwbats I think that part is by design, @ajcvickers might correct me. You could try to work around it by detaching the accounts first, but in general you would need #9118 for this scenario to work correctly. |
@AndriySvyryd EF2.2 simply let the navigational properties sit. I liked it that way. My codebase's architecture kind of depends on it. I have a real usecase where I need this. I want to be able to retrieve-with-props, update and then serialize-to-client-with-props without the hassle of (1) exceptions related to already-attached entities, (2) disappearing nav props and (3) having to re-retrieve to mitigate this. I've already tried detaching the entities in different orders. It made no difference. I'd really appreciate it if there were a way to detach after saving without losing the nav props. Or a global setting such as 'DisableTrackingOnSave' would help. The issue you refer to is still open and doesn't seem to have offered a solid mitigation for this yet. This issue is also not listed as a breaking change, afaik. I welcome feedback from @ajcvickers in this matter. |
@jwbats A few of things to consider. First, the primary purpose for tracking entities is to allow Second, the recommended pattern for use of Third, if there are situations where EF fixup is doing the "wrong thing", then we would appreciate issues being filed for specific cases showing how EF is doing the wrong thing. |
@ajcvickers Thanks for the feedback. First, what you're trying to tell me is that you're supposed to call Update() once on an entity to add it to the context, then SaveChanges() to actually save the changes and also track it... and then you can make more changes to the now-tracked object, and then you only have to call SaveChanges() if you want to save further changes. Do I understand that correctly? Second, I'm familiar with the recommend unit-of-work pattern for DbContext. I use my DbContexts very shortly. I use dependency injection to inject the context into my generic repository. It's registered as having scope for this request only. I call that a single unit-of-work. In this generic reposity, I have a method that does Update(), SaveChanges(), DetachAll(). This way, I am able to retrieve an entity including properties, UpdateSaveDetach() it, modify it a bit, UpdateSaveDetach() it, then serialize it to the clientside. Except with EF3, the nav props are now stripped from the entity. It seems that @AndriySvyryd agrees this is a regression. Also, when I drag the debug pointer back, create a new entity with a child prop and UpdateSaveDetach() it, then for some reason the nav prop stays on (read: different behavior when executing the same, deterministic code for a second time). I will soon try to reproduce this and, if it's really EF3's fault and not my own, create an issue out of it. Third, what do you mean by "EF fixup doing the wrong thing"? |
For me, I use this in unit testing with the following pattern:
Not sure yet what my workaround should be. |
Oh sorry, so far it appears that AndriySvyryd's workaround seems to work. |
This is a bad idea. Creating and deleting DBContext fills up your memory, with allocated and pinned variables, especially if you are doing concurrent work. It looks like EF Dotnet is broken. Creating an re-creating DBContext will result in the garbage collector kicking in and after a while GC will run every second to deal with that. |
I don't believe this issue has anything to do with (re)creating DBContext. Mine is injected in a class that's added with AddScoped() in startup, meaning I get one instance of it per request. This is how the official docs recommend it, iirc. |
I'm upgrading from .NET Core 2.2 to .NET Core 3.0.
I have no interested in tracking entities. I use AsNoTracking() for every retrieval.
Upon saving, entities are being tracked. I want to detach them all.
This worked in .NET Core 2.2 with EF2.2 It no longer works in .NET Core 3.0 with EF3.0.
Steps to reproduce
Have a simple model where a child entity has a non-nullable FK to the parent entity. The parent entity has a navigation property, which is a list that contains child entities.
Retrieve the parent entity, including the child entities on its navigation property.
Then call:
DetachAll() implementation:
This generates an exception that suggests using cascade deletes. I have no desire to delete anything. I merely want to stop tracking everything.
Is there another way of doing this in EF3.0, or am I doing it right and is this really a bug?
In my context's constructor, I even attempt to turn tracking off globally:
Why does this not stop tracking dead in its tracks?
Exception
InvalidOperationException: The association between entity types 'Account' and 'CreditPurchase' has been severed but the relationship is either marked as 'Required' or is implicitly required because the foreign key is not nullable. If the dependent/child entity should be deleted when a required relationship is severed, then setup the relationship to use cascade deletes. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the key values.
Further technical details
EF Core version: 3.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET Core 3.0
Operating system: Win10
IDE: Visual Studio 2019 16.5
The text was updated successfully, but these errors were encountered: