c# - 使用 DbContext API 添加和删除多对多

标签 c# asp.net .net entity-framework-4 dbcontext

我正在使用 Entity Framework 和 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();
}

我没有收到任何错误,但没有保存关系。怎么办?

最佳答案

我引用你的(重要的!)评论:

The objects I send to the method are attached and EntityState is Unchanged. The configuration of my DbContext is, that I have disabled 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 行中更改了 myobjOtherObj 列表之间的关系.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)
    //...
    

也许有可能 - 通过 IObjectContextAdapter 访问 ObjectContext - 手动修改对象状态管理器中的关系条目,但我不知道如何。

在我看来,这种手动操作实体(和关系)状态的过程不是您应该使用 EF 的方式。 AutoDetectChangesEnabled 的引入是为了使使用 EF 更轻松、更安全,唯一建议禁用它的情况是高性能要求(例如批量插入)。如果您在不需要的情况下禁用自动更改检测,您就会遇到此类难以检测的问题,并且需要对 EF 的内部工作原理有深入了解才能修复这些错误。

关于c# - 使用 DbContext API 添加和删除多对多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10783051/

相关文章:

c# - 我应该如何将托管的 DirectX 程序迁移到 Windows 7?

c# - 将项目从使用模拟对象和真实对象切换的模式

c# - Unity 场景管理和 Android - 无法加载场景

c# - 在启用 LowercaseUrls 的情况下在路由参数中保留大小写

C# 模拟单元测试 GraphServiceClient

asp.net - Ajax.BeginForm 与 MVC 不会执行我的操作

c# - 找不到类型或命名空间(是否缺少 using 指令或程序集引用?)

ASP.NET 核心 JWT 身份验证总是抛出 401 未授权

asp.net - 构建基于 Internet 的 p2p 文本、音频、视频聊天应用程序

C#/.Net : Returning a file to the browser?