【问题标题】:How to save child relationship entities in the Entity Framework如何在实体框架中保存子关系实体
【发布时间】:2011-01-18 12:25:06
【问题描述】:

我有一个实体框架 v1 项目。我有两个实体(角色和权限),它们之间具有多对多的关系。我传入一个要保存的对象(通过 WCF 调用,我自己没有从上下文创建它),它在多对多关系中有新条目。

我使用“context.ApplyPropertyChanges”用新属性更新记录。我知道这不会更新关系。我尝试做一个 ChildCollection.Add(relatedObject);或 ChildCollection.Attach(relatedObject).

当我使用“添加”方法时,我收到以下错误:无法将对象添加到 ObjectStateManager,因为它已经有一个 EntityKey。使用 ObjectContext.Attach 附加具有现有键的对象。

当我使用“附加”方法时,我收到以下错误:无法将对象添加到 ObjectStateManager,因为它已经有一个 EntityKey。使用 ObjectContext.Attach 附加具有现有键的对象。

我感到非常沮丧,我想我可以听到实体框架在嘲笑我。

有谁知道我该如何解决这个问题?

MyRole x = context.Roles.FirstOrDefault(a => a.RoleId == this.RoleId);

context.ApplyPropertyChanges("Roles", this);
foreach (MyPermission p in this.Permissions)
{
     x.Permissions.Add(p);
    //  ^ or v
     x.Permissions.Attach(p);
}
context.SaveChanges();

谢谢。

【问题讨论】:

    标签: entity-framework


    【解决方案1】:

    哇。在这个问题上连续 20 个小时左右后,我开始讨厌实体框架。这是当前似乎正在运行的代码。我将不胜感激有关如何使这更加简化的任何建议。

    我确实重新设计了 WCF 服务,以便只有一个数据上下文。谢谢克雷格。

    然后我不得不将代码更改为以下内容:

    MyRole x = context.Roles.FirstOrDefault(a => a.RoleId == this.RoleId);
    
    if (x == null) // inserting
    {
        MyApplication t = this.Application;
        this.Application = null;
        context.Attach(t);
        this.Application = t;
    }
    else // updating
    {
        context.ApplyPropertyChanges("Roles", this);
        x.Permissions.Load();
    
        IEnumerable<Guid> oldPerms = x.Permissions.Select(y => y.PermissionId);
        List<MyPermission> newPerms = this.Permissions.Where(y => !oldPerms.Contains(y.PermissionId)).ToList();
        IEnumerable<Guid> curPerms = this.Permissions.Select(y => y.PermissionId);
        List<MyPermission> deletedPerms = x.Permissions.Where(y => !curPerms.Contains(y.PermissionId)).ToList();
    
        // new 
        foreach (MyPermission p in newPerms)
        {
            x.Permissions.Add(context.Permissions.First(z => z.PermissionId == p.PermissionId));
        }
    
        // deleted
        foreach (MyPermission p in deletedPerms)
        {
            x.Permissions.Remove(context.Permissions.First(z => z.PermissionId == p.PermissionId));
        }
    }
    

    【讨论】:

      【解决方案2】:

      您正在同时使用多个 ObjectContexts(变量 context 以及 this 的来源)。不要那样做。它只会让你的事情变得非常困难。一次使用一个 ObjectContext。

      如果您显示更多代码,我可以提供更具体的建议。

      【讨论】:

      • “this”的上下文由 WCF 生成的代码自动创建。有什么办法可以处理吗?谢谢。
      • 最好使用该上下文而不是创建一个新上下文。再说一次,如果不看代码就很难说。
      【解决方案3】:

      我怀疑您遇到了错误,因为 ObjectContext 认为您正在尝试添加一个新实体,但发现它已经有一个 EntityKey。我使用 ObjectContext 的 AttachTo 方法将我已经存在的实体附加到它们的 EntitySet。我已经从存根生成我的实体或访问数据库的结果。这样,当您将实体添加到实体的导航属性时,ObjectContext 会在其 EntitySet 中找到该实体,并知道它是现有实体而不是新实体。我不知道这是否清楚。如果有帮助,我可以发布一些代码。正如 Stuntz 先生在回答中所说,发布更多代码会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-28
        • 2011-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多