ADO.Netentity frameworkIEntityChangeTracker的多个实例不能引用实体对象

我正在尝试保存我的联系人,其中提到了ContactRelation(只是联系人,已婚,单身等的关系)和国家。 但每当我尝试保存我的联系人时,我都会得到例外“ADO.Netentity framework实例对象不能被IEntityChangeTracker的多个实例引用”

public Contact CreateContact(Contact contact) { _entities.AddToContact(contact); //throws the exception _entities.SaveChanges(); return contact ; } 

我正在使用松散耦合的MVC设计与服务和存储库。 我已经阅读了很多关于这个例外的post,但没有一个给我一个有效的答案……

谢谢你,彼得

[更新]
由于使用了L2E,因此您需要先保存所有链接的对象,然后才能保存主对象。 这是有道理的,否则你会创建(在我的例子中)没有它的联系对象的艺术家。 数据库设计不允许这样做。
[/更新]

这是我的实施工作。

 [AcceptVerbs(HttpVerbs.Post)] public ActionResult Create([Bind(Exclude = "Id")] Artist artist, [Bind(Prefix = "Contact")] Contact contact, [Bind(Prefix = "Country")] Country country, [Bind(Prefix = "ContactRelationship")] ContactRelationship contactRelationship) { ViewData["Countries"] = new SelectList(new CountryService(_msw).ListCountries().OrderBy(c => c.Name), "ID", "Name"); ViewData["ContactRelationships"] = new SelectList(new ContactRelationshipService(_msw).ListContactRelationships().OrderBy(c => c.ID), "ID", "Description"); country = _countryService.GetCountryById(country.ID); contact.Country = country; contactRelationship = _contactRelationshipService.GetContactRelationship(contactRelationship.ID); contact.ContactRelationship = contactRelationship; if(_contactService.CreateContact(contact)){ artist.Contact = contact; if (_service.CreateArtist(artist)) return RedirectToAction("Index"); } return View("Create"); } 

然后在我的ContactRepository中:

 public Contact CreateContact(Contact contact) { _entities.AddToContact(contact); //no longer throws the exception _entities.SaveChanges(); return contact ; } 

我还在这个网站上发现最好在整个应用程序中保持相同的上下文,所以我现在使用一个特殊的Data类:

Rick Strahl和Samuel Maecham告诉我你应该按照每个用户的请求保留你的datacontext。 这意味着将它放在Web应用程序的HttpContext中。 在这里阅读所有相关信息

 public class Data { public static MyDBEntities MyDBEntities { get { if (HttpContext.Current != null && HttpContext.Current["myDBEntities"] == null) { HttpContext.Current["myDBEntities"] = new MyDBEntities (); } return HttpContext.Current["myDBEntities"] as MyDBEntities; } set { if(HttpContext.Current != null) HttpContext.Current["myDBEntities"] = value; } } } 

我以前见过这个,你可能需要在保存之前将Reference字段转换为EntityKey,然后在保存之后加载它。 请尝试使用此代码:

 public Contact CreateContact(Contact contact){ contact.ConvertContactRelationToReference(); _entities.AddToContact(contact); //throws the exception _entities.SaveChanges(); contact.ContactRelation.Load(); return contact; } public partial class Contact { public void ConvertContactRelationToReference() { var crId = ContactRelation.Id; ContactRelation = null; ContactRelationReference.EntityKey = new EntityKey("MyEntities.ContactRelations", "Id", crId); } } 

当然,根据您确切的数据库结构,可能需要更改某些代码。

嗯,我想知道是否有人可以请理智检查我的解决方案。 它与下面接受的答案非常相似,但在阅读了Rick Strahl关于DataContext Life Management的博客后,我担心这不是Web应用程序的线程安全解决方案。

我还通过使用单例模式访问我的对象上下文来绕过我收到此错误消息的实例。

我在MyObjectContext类中添加了以下内容:

 // singleton private static MyObjectContext context; public static MyObjectContext getInstance() { if (context == null) { context = new MyObjectContext (); } return context; } 

在我的每个实体存储库映射器中,而不是实例化我使用的MyObjectContext的新实例

 var db = MyObjectContext.getInstance(); 

我在这里傻吗? 它似乎工作。