Объект с таким же ключом уже существует в objectstatemanager

Много вопросов об этой ошибке, и все же я не могу понять мою проблему (возможно, мне нужно больше теории вокруг этого).

Я получаю сообщение об ошибке "Объект с таким же ключом уже существует в objectstatemanager", и то, что я пытаюсь сделать, настолько просто, у меня просто есть Edit View for client, в котором есть список телефонов. Когда пользователь нажимает кнопку "Сохранить", я просто оборачиваю все с помощью Json и отправляю его на контроллер с помощью Ajax.

На контроллере я должен проверить, какие телефоны из списка отправленных я должен обновить, вставить как новости и удалить.

Итак, вот важная часть кода (и та, которая бросает упомянутое исключение):

            if (ModelState.IsValid)
            {
                foreach (var tel in propModel.Proprietario.Telefones)
                {
                    //Updates
                    TelefoneProprietario telToEdit = null;
                    if (tel.IDTelefoneProprietario.HasValue)
                        telToEdit = db.TelefonesProprietarios.Find(tel.IDTelefoneProprietario);
                    if (telToEdit != null)
                    {
                        db.Entry(tel).State = EntityState.Modified; << Exception HERE!!!
                    }
                    else
                    {
                        //Inserts
                        db.TelefonesProprietarios.Add(tel);
                    }
                }

                if (propModel.Proprietario.IDProprietario.HasValue)
                {
                    var prop = db.Proprietarios.Find(propModel.Proprietario.IDProprietario);
                    prop.LoadLists();
                    foreach (var telDel in prop.Telefones)
                    {
                        //Deletes
                        if (propModel.Proprietario.Telefones.Find(t => t.IDTelefoneProprietario == telDel.IDTelefoneProprietario) == null)
                        {
                            db.TelefonesProprietarios.Remove(telDel);
                        }
                    }
                }

                db.Entry(propModel.Proprietario).State = EntityState.Modified;
                db.SaveChanges();

                return Json(new { Success = 1, IDProprietario = propModel.Proprietario.IDProprietario, ex = "" });
            }

Любая помощь или предложения?

И, что еще хуже: я взял строку, выбрасывающую исключение, просто для проверки остальной части кода, а в последней строке перед SaveChanges выдает еще одно исключение:

The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.

ОБНОВИТЬ:

Мне удается решить часть проблемы, переписав приведенную выше подпрограмму в другой форме, например так:

                if (prop.IDProprietario.HasValue)
                {
                    //Separete updates/inserts from deletes
                    List<int?> dbTels = db.TelefonesProprietarios
                                    .Where(dt => dt.IDProprietario == prop.IDProprietario)
                                    .Select(dt => dt.IDTelefoneProprietario)
                                    .ToList();

                    List<int?> postedTels = prop.Telefones
                        .Select(pt => pt.IDTelefoneProprietario)
                        .ToList();

                    List<int?> deletedTels = dbTels
                        .Except(postedTels).ToList();

                    //Perform deletes
                    foreach (var delTelId in deletedTels)
                    {
                        if (delTelId.HasValue)
                        {
                            TelefoneProprietario delTel = db.TelefonesProprietarios
                                .Where(dt => dt.IDProprietario == prop.IDProprietario && dt.IDTelefoneProprietario == delTelId)
                                .Single();

                            db.Entry(delTel).State = EntityState.Deleted;
                        }
                    }

                    //Perform insert and updates
                    foreach (var tel in prop.Telefones)
                    {
                        if (tel.IDTelefoneProprietario.HasValue)
                        {
                            db.Entry(tel).State = EntityState.Modified;
                        }
                        else
                        {
                            db.Entry(tel).State = EntityState.Added;
                            tel.IDProprietario = (int)prop.IDProprietario;
                        }
                    }

                    db.Entry(prop).State = EntityState.Modified;
                }
                else 
                {
                    db.Proprietarios.Add(prop);
                }
                db.SaveChanges();

Единственная проблема, которая осталась сейчас, - это удаление экземпляра Proprietario (поскольку у него есть список TelefonePprietario, а у TelefonePprietario есть ссылка на Proprietario, которому он принадлежит. Этот кенарий приводит к тому, что "отношения между двумя объектами не могут быть определены, поскольку они прикреплены к различные объекты ObjectContext ", как это широко обсуждается здесь, в SO... Попытка найти решение, так что если вы можете указать мне что-то...)

1 ответ

Решение

Когда вы делаете это: db.Entry(tel).State = EntityState.Modified;

тел объект - это просто объектная модель, которую вы передаете, верно?

Таким образом, контекст EF в настоящее время не отслеживает какой-либо объект, имеющий тот же ключ, что и ключ tel, в этом случае IDTelefonePprietario

Поэтому, если вы установите состояние объекта на Modified, то SaveChanges () EF выдаст ошибку.

Сделайте это вместо этого:

if (telToEdit != null)
{
    // Do apply all the changes from 'tel' to 'telToEdit' object here
    ...
    db.Entry(telToEdit).State = EntityState.Modified; // No Exception I hope :)
}

Надеюсь, это имеет смысл.

Другие вопросы по тегам