ADO.Net实体框架IEntityChangeTracker的多个实例不能引用实体对象

ado.net c# entity-framework

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

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

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

谢谢你,彼得

一般承认的答案

[更新]
由于使用了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);
  }
}

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




许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因