实体框架 Context.Refresh 错误的解决方法?
我使用 EF4 和自引用表遇到这个问题(实现邻接列表层次结构)。
注意:不是多对多引用,只是单个表上的一对多。
尝试使用 Context.Refresh
解决间歇性 InvalidOperationException
(“...ObjectContext 可能处于不一致的状态...”)失败由于 EF4 中的一个明显错误。
我从上述帖子中的 Shimmy 的 connect.microsoft.com 链接中看到,该错误仍然存在。
谁能推荐一个解决方法?
如果您的数据库和实体框架不同步,您该怎么办?
编辑
更多可能有帮助的事实:
- 当我收到
InvalidOperationException
且消息显示“对数据库的更改已成功提交...”时,事实并非如此真的。他们不是。 我尝试将对象的ParentId
从 1 更改为 null(ParentId
类型为int?
)。 - 我的对象的
ParentId
属性已正确更改为预期值 (null)。我调用 Context.SaveChanges()。然后,抛出异常。我检查了数据库,发现该值未已更新。在这种情况下,ParentId
在数据库中仍然是1。 - 在
catch
内,如果我尝试通过myObj = Context.MyObjects.SingleOrDefault(o => o.Id == id)
,<重新查询对象br> 对象的ParentId
保持不变。它不会被(不正确的)数据库值更新!
现在我想,好吧,这看起来很奇怪,但也许如果我再次保存,数据库就会得到纠正。 - 从
内部调用后续的
仍然不更新数据库。 (但这一次,不会引发异常。)Context.SaveChanges()
catch - 如果我对 SetParent 方法进行新调用,
myObj = Context.MyObjects.SingleOrDefault(o => o.Id == id)
,
正确地将对象的ParentId
参数填充为 1,即数据库中的值。
此外,为了咯咯笑,我将对象的 ParentId
设置为它自己的 Id,而不是 null,以表示无父项。这工作正常并且没有导致 InvalidOperationException 。但是,由于其他原因,它成为 PITA。例如,该对象报告将自己作为一个额外的子对象。
所以,问题是:
- 尝试设置我的自引用
int 是什么意思? ParentId
为 null 会导致异常? - 为什么数据库在异常发生之前没有更新?
- 为什么在
catch
中我无法重新同步?!
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 intermittent InvalidOperationException
("...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 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.
So, the questions are:
- 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?!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
通过上下文从数据库重新查询对象...
编辑 - 为了响应您的更新,如果您在上下文中提交对对象的更改,则会发生错误,最有可能使用相同的上下文问题。尝试在 catch 中重新创建上下文以重新查询和重新更新,看看是否效果更好。
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.