我引用你的(重要的!)评论:
我发送给该方法的对象已附加并且 EntityState 是 Unchanged。我的 DbContext 的配置是,我禁用了 AutoDetectChangesEnabled ...
因此,您的代码将如下所示:
DbContext.Configuration.AutoDetectChangesEnabled = false;
DbContext.Entry(myobj).State = EntityState.Unchanged;
foreach (OtherObj otherObj in otherObjList)
DbContext.Entry(otherObj).State = EntityState.Unchanged;
// entering MyObj_Save method here
foreach (OtherObj otherObj in otherObjList)
{
//DbContext.OtherObj.Attach(otherObj); // does not have an effect
myobj.OtherObj.Add(otherObj);
}
DbContext.Entry(myobj).State = EntityState.Added;
DbContext.SaveChanges();
这确实不起作用,因为 EF 没有注意到您已经更改了与行中myobj
的列表之间的关系,因为您禁用了自动更改检测。因此,不会将任何条目写入连接表。只有自己会得救。OtherObj
myobj.OtherObj.Add(otherObj);
myobj
您不能在实体上设置任何状态以将状态管理器置于保存关系的状态,因为它不是此处重要的实体状态而是关系状态。这些是对象状态管理器中的单独条目,由更改检测创建和维护。
我看到三个解决方案:
放DbContext.Configuration.AutoDetectChangesEnabled = true;
DetectChanges
手动调用:
//...
DbContext.Entry(myobj).State = EntityState.Added;
DbContext.ChangeTracker.DetectChanges();
DbContext.SaveChanges();
myobj
在将新内容设置为状态之前将其从上下文中分离出来Added
(这对我来说感觉很hacky):
// entering MyObj_Save method here
DbContext.Entry(myobj).State = EntityState.Detached;
foreach (OtherObj otherObj in otherObjList)
//...
也许有可能 - 通过ObjectContext
通过IObjectContextAdapter
- 手动修改对象状态管理器中的关系条目,但我不知道如何。
在我看来,手动操作实体(和关系)状态的过程不是您应该使用 EF 的方式。AutoDetectChangesEnabled
已引入以使使用 EF 更轻松、更安全,唯一推荐禁用它的情况是高性能要求(例如对于批量插入)。如果您在不需要的情况下禁用自动更改检测,则会遇到此类难以检测的问题,并且需要对 EF 的内部工作原理有深入了解才能修复这些错误。