How to save child relationship entities in the Entity Framework
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.ApplyProperty开发者_C百科Changes" 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));
}
}
You are using multiple ObjectContexts concurrently (the variable context
and whereever this
came from). Don't do that. It will only make things very difficult for you. Use one ObjectContext at a time.
I can give more specific advice if you show more code.
I suspect you are getting the errors because the ObjectContext thinks you are trying to add a new entity but finds it already has a EntityKey. I use the AttachTo method of the ObjectContext to attach my already existing entities to their EntitySet. I have had results generating my entities from stubs or hitting the database. This way when you add the entity to the navigation property on your entity, the ObjectContext finds the entity in it's EntitySet and knows it is an existing entity and not a new one. I don't know if this is clear. I could post some code if it would help. As Mr Stuntz said in his answer, posting more of your code would help.
精彩评论