ADO.Net Entity Framework На объектный объект нельзя ссылаться несколькими экземплярами IEntityChangeTracker

ado.net c# entity-framework

Вопрос

Я пытаюсь сохранить свой контакт, в котором есть ссылки на ContactRelation (только отношения контакта, женат, холост и т. Д.) И страны. Но каждый раз, когда я пытаюсь сохранить свой контакт, который проверяется, я получаю исключение "ADO.Net Entity Framework. Объектный объект не может быть указан несколькими экземплярами 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 для этого:

Рик Страл и Сэмюэль Маечам научили меня, что вы должны хранить свой текстовый текст для каждого пользователя по запросу. Это означает, что нужно поместить его в 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);
  }
}

Конечно, часть этого кода может потребоваться изменить в зависимости от вашей точной структуры базы данных.



Related

Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow