如何在实体框架中保存子关系实体 [英] How to save child relationship entities in the Entity Framework

查看:88
本文介绍了如何在实体框架中保存子关系实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Entity Framework v1项目。我有两个实体(角色和权限),它们之间存在多对多的关系。我传递一个要保存的对象(通过WCF调用,我不会自己创建它),它在多对多关系中有新的条目。



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



当我使用添加方法时,我收到错误that:该对象不能添加到ObjectStateManager,因为它已经有一个EntityKey。使用ObjectContext.Attach附加具有现有密钥的对象。



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



我感到很沮丧,我想我可以听到实体框架对我笑了。有没有人知道我如何解决这个问题?

  MyRole x =上下文.Roles.FirstOrDefault(a => a.RoleId == this.RoleId); 

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

谢谢。

解决方案

哇。在这个问题上连续20个小时之后,我开始讨厌实体框架。以下是目前正在工作的代码。我很乐意任何关于如何使其更加精简的建议。



我做了WCF服务的重做,这样只有一个数据上下文。感谢Craig。



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

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

if(x == null)//插入
{
MyApplication t = this.Application;
this.Application = null;
context.Attach(t);
this.Application = t;
}
else //更新
{
context.ApplyPropertyChanges(Roles,this);
x.Permissions.Load();

IEnumerable&Guid。 oldPerms = x.Permissions.Select(y => y.PermissionId);
列表< MyPermission> newPerms = this.Permissions.Where(y =>!oldPerms.Contains(y.PermissionId))。ToList();
IEnumerable&Guid。 curPerms = this.Permissions.Select(y => y.PermissionId);
列表< MyPermission> deletedPerms = x.Permissions.Where(y =>!curPerms.Contains(y.PermissionId))。ToList();

// new
foreach(newPerms中的MyPermission p)
{
x.Permissions.Add(context.Permissions.First(z => z.PermissionId == p.PermissionId));
}

//删除
foreach(deletePerms中的MyPermission p)
{
x.Permissions.Remove(context.Permissions.First(z = > z.PermissionId == p.PermissionId));
}
}


I have an Entity Framework v1 project. I have two entities (Roles and Permissions), which have a many-to-many relationship with each other. I pass in a object to be saved (through a WCF call, I do not create it from a context myself), which has new entries in the many-to-many relationship.

I use "context.ApplyPropertyChanges" to update the record with the new properties. I know that this does not update relationships though. I attempt to either do a ChildCollection.Add(relatedObject); or ChildCollection.Attach(relatedObject).

When I use the "Add" method, I get the error that: The object cannot be added to the ObjectStateManager because it already has an EntityKey. Use ObjectContext.Attach to attach an object that has an existing key.

When I use the "Attach" method, I get the error that: The object cannot be added to the ObjectStateManager because it already has an EntityKey. Use ObjectContext.Attach to attach an object that has an existing key.

I am getting quite frustrated, and I think I can hear the Entity Framework laughing at me.

Does anyone know how I can resolve this?

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();

Thanks.

解决方案

Wow. After 20 or so straight hours on this problem, I'm starting to hate the Entity Framework. Here is the code that appears to be working currently. I would appreciate any advice on how to make this more streamlined.

I did rework the WCF service so that there is only the one data context. Thanks Craig.

Then I had to change the code to the following:

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));
    }
}

这篇关于如何在实体框架中保存子关系实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆