使用 DbContext API 添加和删除多对多
本文关键字:删除 添加 DbContext API 使用 | 更新日期: 2023-09-27 18:35:28
我正在使用实体框架和 DbContext API 确实构建了我的应用程序,但我在使用具有多对多关系的对象时遇到问题。简化的保存方法可能如下所示
public void MyObj_Save(MyObj myobj)
{
DbContext.Entry(myobj).State = EntityState.Added;
DbContext.SaveChanges();
}
此代码工作正常,但如果 MyObj 包含多对多关系,则不会保存此关系。我从使用旧的 POCO API 中知道我需要将相关对象附加到上下文中,但我找不到使用 DbContext API 正确执行此操作的方法 - 下面的简化示例
public void MyObj_Save(MyObj myobj, List<OtherObj> otherObjList)
{
foreach (OtherObj otherObj in otherObjList)
{
DbContext.OtherObj.Attach(otherObj);
myobj.OtherObj.Add(otherObj);
}
DbContext.Entry(myobj).State = EntityState.Added;
DbContext.SaveChanges();
}
我没有收到错误,但关系没有保存。怎么办?
我引用你的(重要!)评论:
我发送到该方法的对象已附加,并且实体状态为 不变。我的数据库上下文的配置是,我已经禁用了 自动检测更改已启用...
因此,您的代码将如下所示:
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
与行myobj.OtherObj.Add(otherObj);
中OtherObj
列表之间的关系,因为您禁用了自动更改检测。因此,不会将任何条目写入连接表。只有myobj
本身才能被保存。
不能在实体上设置任何状态以将状态管理器置于保存关系的状态,因为它不是此处重要的实体状态,而是关系状态。这些是对象状态管理器中的单独条目,由更改检测创建和维护。
我看到三个解决方案:
设置
DbContext.Configuration.AutoDetectChangesEnabled = true;
手动呼叫
DetectChanges
://... DbContext.Entry(myobj).State = EntityState.Added; DbContext.ChangeTracker.DetectChanges(); DbContext.SaveChanges();
在将新
myobj
设置为Added
状态之前,将其从上下文中分离出来(这对我来说感觉很笨拙):// entering MyObj_Save method here DbContext.Entry(myobj).State = EntityState.Detached; foreach (OtherObj otherObj in otherObjList) //...
也许有可能 - 通过IObjectContextAdapter
进入ObjectContext
- 手动修改对象状态管理器中的关系条目,但我不知道如何。
在我看来,手动操作实体(和关系)状态的过程不是您应该使用 EF 的方式。 引入了AutoDetectChangesEnabled
,使使用 EF 更轻松、更安全,禁用它的唯一建议情况是高性能要求(例如,对于批量插入)。如果在不需要的情况下禁用自动更改检测,则会遇到此类难以检测的问题,并且需要对EF内部工作原理的高级了解才能修复这些错误。
public void MyObj_Save(MyObj myobj, List<OtherObj> otherObjList)
{
DbContext.Entry(myobj).State = EntityState.Added;
foreach (OtherObj otherObj in otherObjList)
{
(((System.Data.Entity.Infrastructure.IObjectContextAdapter)DbContext)
.ObjectContext)
.ObjectStateManager
.ChangeRelationshipState(myobj, otherObj,
q => q.OtherObjs, EntityState.Added);
}
DbContext.SaveChanges();
}
同样,这是一个简化的而不是现实生活中的例子!