Entity Framework incorrectly saves an object when I never added it to the context

I am using Entity Framework in .NET 4.0. I have a Subscription object that has many CFile objects. I am creating a new CFile , but I am not really calling it AddObject . Later, I try to save the Subscription object that is associated with it, and EF tries to save the CFile instance that I never planned!

Simplified code:

 var subscription = new Subscription(); Context.Subscription.AddObject(subscription); Context.SaveChanges(); var cfile = new CFile() { Subscription = subscription }; if (SomeChecksPass(cfile)) { Context.CFiles.AddObject(cfile); } else { // No AddObject! } subscription.SomeProperty = "changed"; Context.SaveChanges(); // Saves cfile as well, even if I don't want to! 

I understand why this is happening, but how can I get him not to do this? This creates a rather subtle and incomprehensible error (the real code is obviously much more complicated). I want it to save only objects that I explicitly passed to AddObject .

I also know about a Detach : call Detach on an entity that I don't want to save. However, this is not a good workaround, because I have to make sure that I call Detach in all possible codes where CFile not saved (and in some codes it is saved), so it should be called after this solution but before anything still be preserved. It is very fragile, and I really do not want to rely on it.

Edit: CFile is created because I want to save it most of the time, but if some verification fails or some error occurs, I do not. I still want to save some changes to the Subscription object.

+4
source share
3 answers

Try to open the foreign key in your EDMX (if it does not already exist) and do something like this:

 var cfile = new CFile() { SubscriptionId = subscription.Id }; 

This should be enough to prevent the formation of an object graph.

You may need to call Refresh on the subscription object after it is created (depending on how your identifiers are generated), most of them will be updated automatically when you SaveChanges ()).

+1
source

You do not directly control which entities are stored in the Entity Framework, this saves what, in his opinion, should, it works with related object graphs. You can put some logic in ObjectContext.SaveChanges to override with ObjectStateManager, but it's pretty ugly.

If you need more control over what to save and when, maybe it's better to use some other template, for example, Repository | ActiveRecord, where you better manage individual objects. Or you will often find yourself in situations that you described.

+1
source

I had the same issue when using:

 List<Ey> eys = dc.Context.Ey.ToList(); eys = eys .Where(h => h.Employee == myEmployee).ToList(); Ey esh; for (int k = 1; k < 5; k++) { EmployeeSkillHistory duplicate = histories.Where(h => h.Sl == esh.Sl).FirstOrDefault(); if (duplicate == null) { dc.Context.Ey.AddObject(esh); } else { dc.Context.Ey.DeleteObject(esh); } dc.Context.SaveChanges(); } 

Before use

 else { dc.Context.Ey.DeleteObject(esh); } 

Duplicates were saved in my database

+1
source

Source: https://habr.com/ru/post/1332303/


All Articles