我有一个Entity Framework v1项目。我有两个实体(角色和权限),它们之间具有多对多的关系。我传入一个要保存的对象(通过WCF调用,我不是自己创建一个上下文),它在多对多关系中有新的条目。
我使用“context.ApplyPropertyChanges”来更新具有新属性的记录。我知道这不会更新关系。我尝试做一个 ChildCollection .Add( relatedObject );或 ChildCollection .Attach( relatedObject )。
当我使用“Add”方法时,我得到的错误是:无法将对象添加到ObjectStateManager,因为它已经有一个EntityKey。使用ObjectContext.Attach附加具有现有密钥的对象。
当我使用“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();
感谢。
答案 0 :(得分:2)
哇。在这个问题连续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));
}
}
答案 1 :(得分:0)
您正在同时使用多个ObjectContexts(变量context
和this
来自)。不要那样做。它只会让你很难。一次使用一个ObjectContext。
如果您显示更多代码,我可以提供更具体的建议。
答案 2 :(得分:0)
我怀疑你收到了错误,因为ObjectContext认为你试图添加一个新实体,但发现它已经有了一个EntityKey。我使用ObjectContext的AttachTo方法将我已经存在的实体附加到它们的EntitySet。我有从存根或命中数据库生成我的实体的结果。这样,当您将实体添加到实体的导航属性时,ObjectContext会在其EntitySet中查找实体,并且知道它是现有实体而不是新实体。我不知道这是否清楚。我可以发布一些代码,如果它会有所帮助。正如Stuntz先生在答案中所说,发布更多代码会有所帮助。