Workaround for Entity Framework Context.Refresh bug?
I ran into this problem using EF4 and a self-referential table (implementing an adjacency list hierarchy).
NOTE: not a many-to-many reference, just a one-to-many on a single table. Attempts to resolve an intermittentInvalidOperationException
("...The ObjectContext might be in an inconsistent state...") using Context.Refresh
fail due to an apparent bug in EF4.
I saw, from following Shimmy's connect.microsoft.com link, on the aforementioned post, that the bug is still outstanding.
Can anyone recommend a workaround? What do you do if your database and Entity Framework get out of sync?EDIT
Some more facts that may help:- When I get the
InvalidOperationException
and the message says "The changes to the database were committed successfully...", it is not true. They weren't. I tried to change an object'sParentId
from 1 to null (ParentId
of typeint?
). - My object's
ParentId
attribute is correctly changed to the expected value (null). I callContext.SaveChanges()
. Then, the exception is thrown. I check the DB, and the value has not been updated. In this case,ParentId
is still 1 in the database. - Inside the
catch
, if I try to requery the object viamyObj = Context.MyObjects.SingleOrDefault(o => o.Id == id)
, the object'sParentId
remains the same. It does not get 开发者_StackOverflow中文版updated by the (incorrect) database value! Now I think, Okay, that seems weird, but maybe if I save again the db will be corrected. - Calling a subsequent
Context.SaveChanges()
from inside thecatch
still does not update the database. (But this time, an exception is not thrown.) - If I make a new call to my SetParent method,
myObj = Context.MyObjects.SingleOrDefault(o => o.Id == id)
, correcly populates the object'sParentId
parameter to 1, the value from the database.
Additionally, for giggles, I set the object's ParentId
to it's own Id, instead of null, to denote parentlessness. This worked fine and did not cause the InvalidOperationException
. But, it's a PITA for other reasons. E.g., the object reports having itself as an extra child.
- What is it about trying to set my self-referential
int? ParentId
to null that causes an exception? - Why does the db not get updated before the exception?
- And why, inside the
catch
, can't I resync?!
Requery the object from the database through the context...
EDIT - in response to your update, if you submit changes for an object within a context, an an error happens, using the same context most likely is the problem. Try recreating the context in the catch to requery and reupdate, and see if that works any better.
精彩评论