只是出于我的好奇心(以及未来的知识),Entity Framework 5 如何决定何时创建新对象与引用现有对象?我可能只是做错了什么,但似乎时不时地,如果我做一些类似的事情:
using (TestDB db = new TestDB())
{
var currParent = db.Parents.Where(p => p.Prop == passedProp).FirstOrDefault();
if(currParent == null) {
Parent newParent = new Parent();
newParent.Prop = passedProp;
currParent = newParent;
}
//maybe do something to currParent here
var currThing = db.Things.Where(t => t.Prop == passedPropTwo).FirstOrDefault();
currThing.Parent = currParent;
db.SaveChanges();
}
EF 将在数据库中创建一个新的 Parent,基本上是 currParent 的副本,然后将 currThing 的 Parent_ID 值设置为该副本。然后,如果我再次执行此操作(例如,如果已经有两个父级),它不会创建新的父级,而是链接到第一个父级。我不太理解这种行为,但在玩了一段时间之后,类似:
using (TestDB db = new TestDB())
{
var currParent = db.Parents.Where(p => p.Prop == passedProp).FirstOrDefault();
if(currParent == null) {
Parent newParent = new Parent();
newParent.Prop = passedProp;
currParent = newParent;
}
//maybe do something to currParent here
var currThing = db.Things.Where(t => t.Prop == passedPropTwo).FirstOrDefault();
currThing.Parent = db.Parents.Where(p => p.ID == currParent.ID).First();
db.SaveChanges();
}
似乎解决了问题。是否有任何我应该注意的原因可能会发生这种情况,或者我当时的做法是否有些奇怪?抱歉,我无法更具体地说明确切的代码是什么,我不久前遇到过这个问题并用上面的代码修复了它,所以我没有看到任何理由询问它。更一般地说,EF 如何决定是否引用现有项目而不是创建新项目?仅仅根据ID设置与否?谢谢!
如果您的具体实例DBContext
向您提供该实体的特定实例,那么它将知道它代表数据库中的哪些记录,并且您对其所做的任何更改都将适用于数据库中的该(那些)记录。如果你自己实例化一个新实体,那么你需要告诉DBContext
如果该记录不是应插入数据库的新记录,那么该记录到底是什么。
在特殊场景下,你有多个DBContext
实例,一个实例为您提供了该实体,但您想使用另一个实例来处理并保存该实体,那么您必须使用((IObjectContextAdapter)firstDbContext).ObjectContext.Detach()
孤立这个实体然后使用((IObjectContextAdapter)secondDbContext).ObjectContext.Parents.Attach()
附加它(或ApplyChanges()
如果您也在编辑它 - 这将调用Attach
为你)。
在其他一些特殊场景中(您的对象已被序列化和/或您有自我跟踪实体),可能需要一些额外的步骤,具体取决于您到底想要做什么。
总而言之,如果您的具体实例DBContext
“知道”实体的特定实例,然后它将使用它,就好像它直接绑定到数据库中的特定行一样。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)