无法定义两个对象之间的关系,因为它们附加到不同的ObjectContext对象

我已经阅读了一些与此特定错误消息有关的问题/答案,但我不太了解相应的解决方案。

我已多次读过你应该创建EF4上下文,使用它,然后处理它。 在我的应用程序中,我使用不同的上下文对象在这里和那里加载实体,然后最终想要将实体关联在一起。

我创建了一个简单的控制台应用程序,很容易导致错误。 图中显示了非常简单的模型,然后是代码。

如何让两个不同的实体共享相同的上下文? 我是否真的必须创建一个新的上下文,再次加载这两个实体(即使我已经拥有它们),只需关联它们并保存?

如果我只是错过了现有的,适当的问题/答案,请指出我正确的地方。

简单的EF4模型图

internal class Program { private static void Main(string[] args) { DeleteAllEntities(); CreateInitialEntities(); Owner o = LoadOwner(); Child c = LoadChild(); AssociateAndSave(o, c); } private static void AssociateAndSave(Owner o, Child c) { using (var context = new ModelEntities()) { // Exception occurs on the following line. o.Children.Add(c); context.Attach(o); context.SaveChanges(); } } private static Owner LoadOwner() { using (var context = new ModelEntities()) { return ((from o in context.Owners select o).First()); } } private static Child LoadChild() { using (var context = new ModelEntities()) { return ((from c in context.Children select c).First()); } } private static void CreateInitialEntities() { using (var context = new ModelEntities()) { Owner owner = new Owner(); Child child = new Child(); context.Owners.AddObject(owner); context.Children.AddObject(child); context.SaveChanges(); } } private static void DeleteAllEntities() { using (var context = new ModelEntities()) { List children = (from c in context.Children select c).ToList(); foreach (var c in children) context.Children.DeleteObject(c); List owners = (from o in context.Owners select o).ToList(); foreach (var o in owners) context.Owners.DeleteObject(o); context.SaveChanges(); } } } 

您应该在相同的上下文中获得对子对象和所有者对象的引用。 一种方法是获取id,然后将它们作为参数传递给AssociateAndSave(int oId, int cId)方法。

然后, 在同一上下文中检索对对象的引用,然后创建附件。

 private static void Main(string[] args) { DeleteAllEntities(); CreateInitialEntities(); int oId = LoadOwnerId(); int cId = LoadChildId(); AssociateAndSave(oId, cId); } private static int LoadOwnerId() { using (var context = new ModelEntities()) { return (from o in context.Owners select o).First().Id; } } private static int LoadChildId() { using (var context = new ModelEntities()) { return (from c in context.Children select c).First().Id; } } private static void AssociateAndSave(int oId, int cId) { using (var context = new ModelEntities()) { var owner = (from o in context.Owners select o).FirstOrDefault(o => o.ID == oId); var child = (from o in context.Children select o).FirstOrDefault(c => c.ID == cId); owner.Children.Add(child); context.Attach(owner); context.SaveChanges(); } } 

您无法使用另一个上下文的实例从一个上下文中删除对象,因为每个上下文都会单独跟踪其对象。

一个想法是为您的每个方法提供上下文类型的参数,以便您的操作在相同的上下文中进行。

EX:

 private static void CrudOperationExample(DBContext contextInstane) { //perform crud operations. } 

我想你做得更好,我建议你寻找dependency injection,因为它在ORM中非常有帮助。