Объект с тем же ключом уже существует в ObjectStateManager. ObjectStateManager не может отслеживать несколько объектов с одним и тем же ключом
У меня есть следующий код для добавления или обновления объекта Entity. поиск объекта по первичному ключу, основанный на ответе, который я добавляю или обновляю.
Добавление записи работает, но во время обновления появляется сообщение об ошибке " Объект с тем же ключом уже существует в ObjectStateManager. ObjectStateManager не может отслеживать несколько объектов с одним и тем же ключом
В моей базе данных MSSQL у меня есть только одна запись.
var v = db.Envelopes.Find(model.ReportDate, model.Service);
if (v == null)
{
db.Envelopes.Add(model);
db.SaveChanges();
ViewBag.status = "Record Add successfully";
ModelState.Clear();
}
else
{
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
}
Как я могу исправить это сообщение об ошибке?
Ответы
Ответ 1
Как уже упоминалось @anon, вы не можете присоединить модель, как только вы загрузили объект с тем же ключом. Изменения должны применяться к прикрепленному объекту. Вместо этого:
db.Entry(model).State = EntityState.Modified;
используйте это:
db.Entry(v).CurrentValues.SetValues(model);
Ответ 2
Если предыдущий запрос прочитал объект, который будет обновлен, и почему вы получаете сообщение об ошибке, вы можете изменить этот запрос на AsNoTracking. См. Пример AsNoTracking в:
http://www.asp.net/entity-framework/tutorials/advanced-entity-framework-scenarios-for-an-mvc-web-application
Ответ 3
Я предполагаю, что вы говорите, что ваша ошибка возникает здесь:
db.Entry(model).State = EntityState.Modified;
После выполнения функции Find() ваш конверт уже отслеживается вашим контекстом. Это означает, что если вам нужно изменить свойство, просто измените его на v, а затем вызовите SaveChanges(). Не беспокойтесь о настройке состояния на Модифицировано.
Ответ 4
Если вы установите свой контекст в AsNoTracking(), это остановит aspmvc отслеживание изменений в сущности в памяти (это то, что вы хотите в любом случае в Интернете). Не забывайте использовать инструкцию.
using System.Data.Entity;
db.Envelopes.AsNoTracking().Find(model.ReportDate, model.Service);
Я получил это из этого сообщения на форуме → http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application
Ответ 5
Я использую это, потому что я уже создал новый экземпляр и заполнил свойства, которые мне нужно обновить.
var key=this.CreateEntityKey("Envelopes",model);
ObjectStateEntry ose;
if(this.ObjectStateManager.TryGetObjectStateEntry(key, out ose)){
var entity=(Page)ose.Entity;
Envelopes.Detach(entity);
}
this.Envelopes.Attach(model);
Ответ 6
И еще один подход к решению проблемы - удаление отслеживаемого объекта и повторная установка измененного. См. Мое решение здесь.