简版: 当我做了“myDbContext.Add(Entity)”时,我添加了2个实体,我刚才查询,但也添加到dbContext一个子实体(与我查询的第一个实体有关),似乎EF没有跟踪他们作为存在,因为试图插入Parent和Child实体。为什么我的dbContext的Add方法会添加2个父实体和1个导致PK约束错误的子实体
我不能添加特定的代码,因为政策,但基本上我做这样的事情:
using (var db = new MyEntitiesContext())
{
/*don't know why, but code was already like this,
has some method which returns list of
SomeEntity type even knowing will have only 1 object*/
List<SomeEntity> entities = new List<SomeEntity>
entities = SomeMethod.SearchEntities(id);
SomeEntity current = entities.FirstOrDefault();
SomeEntity newOne = new SomeEntity();
//Then notice I use some of the values (all of them are int/string/date)
//from the "current" object to populate the "newOne"
newOne.Id = (from p in db.SomeEntities select p.Id).Max() + 1;
newOne.SomeDateValue = current.SomeDateValue;
newOne.someStringValue = current.someStringValue;
.
. //add some other values which doesnt' seem relevant to the issue
.
db.SomeEntity(newOne);
db.SaveChanges();
}
出于某种原因SaveChanges方法将导致相关的子实体违反的PK约束的例外。
经过调试和做一些“手表”,我注意到我的dbContext对象“db”实际上持有SomeEntity的2个实体,“newOne”和“当前”我可以注意到,因为“Count”值db.SomeEntity.Local属性。
出于某种原因(糟糕的设计/理解)这样做时:
db.SomeEntity.Add(newOne)
“当前”的实例加入以及旁边一个孩子实体“地位”,所以调用SaveChanges()尝试重新插入一个现有的“状态”实体(除现有的“当前”实体外),并且将该异常抛出到SaveChanges()方法中。
我似乎可以分离是导致冲突的对象,是“当前”实体解决这个问题,它的子实体“状态”,从的DbContext对象,但
这是为什么发生?或者我该如何避免这种情况?
我唯一的看法是,将值从“current”分配给“newOne”时可能导致行为的一些参考,注意到“status”子实体没有从“current”分配给“newOne”,I试图使用“status”实体的新实例进行分配,并将其保留为空,但没有一个解决了这个问题。
note:我试图在不同的“使用”块中查询“当前”对象,但问题依然存在。
注2:代码编译和被执行以及直到SaveChanges方法,上述样品是不实际的代码,但缩短/虚构版本试图代表具有该问题的实际代码的相同部分,因此一些语法/其他错误可以在上面的代码中可以发现,问题更涉及到我缺乏的实体框架是如何工作和知识/或进行添加/调用SaveChanges
最后更新 的SearchEntities方法使用时跟踪实体一个不同的上下文,通过在不同的上下文中“缓存”实体我导致EF将它们标记为新的 - 插入,我只是拿着那个代码在同一个dbContext中使用它,在那里我插入一个新的实体并解决问题,似乎这是一个非常普遍的问题,但由于每个开发人员都陷入陷阱,所以这是一个非常普遍的问题。
你确定你的“类似”代码也编译和*产生相同的问题*? –
@Damien_The_Unbeliever不,不幸的是,我刚刚创建的样本确实按预期工作,实际上我在数据库对象中看到2个“SomeEntity”,但子实体没有被添加到数据库对象,并且SaveChanges方法无误地执行,所以这个问题不存在,但即使在分离子实体的“真实”问题中,“当前”导致其 – Allende
表上的PK冲突,我认为上下文将保存2个值,因为正在跟踪的实体.. –