Ошибка ObjectStateManager при добавлении вторых данных (Entity Framework)
При добавлении нескольких последовательных данных в методе SaveChanges() произошла ошибка.
ИСКЛЮЧЕНИЕ Изменения в базе данных были успешно зафиксированы, но при обновлении контекста объекта произошла ошибка. ObjectContext может быть в несовместимом состоянии. Внутреннее сообщение об исключении: AcceptChanges не может продолжаться, поскольку значения ключа объекта конфликтуют с другим объектом в ObjectStateManager. Убедитесь, что значения ключей являются уникальными, прежде чем вызывать AcceptChanges.
Мой базовый сервис
public void Delete(T entity)
{
ObjectSet.DeleteObject(entity);
Context.SaveChanges();
}
public void Add(T entity)
{
ObjectSet.AddObject(entity);
Context.SaveChanges();
}
public void Attach(T entity)
{
ObjectSet.Attach(entity);
Context.SaveChanges();
}
public void Update(Expression<Func<T, bool>> where, T entity)
{
var ent = First(where);
ent = entity;
Context.SaveChanges();
}
2 ответа
Вы уверены, что добавляете разные объекты в EF? Внутреннее исключение гласит, что AcceptChanges()
не удается, потому что текущий объект, который вы пытаетесь добавить, делит ключ с объектом, который уже отслеживается.
Для больше на AcceptChanges()
посмотрите на: http://msdn.microsoft.com/en-us/library/system.data.objects.objectstateentry.acceptchanges.aspx
У меня была эта проблема, и я обнаружил, что выполняю следующие операции, заставляя EntityFramework не синхронизироваться с данными в базе данных:
1) Сделайте запрос по строкам таблицы через контекст Entity Framework. При этом контекст EntityFramework сохраняет копию этих объектов в своем локальном представлении.
2) Усечь таблицу с помощью SQL-запроса (поэтому контекст Entity Framework не знает, что это произошло. Объекты все еще находятся в своем локальном представлении, даже если они были усечены в базе данных). Поскольку первичным ключом таблицы является автоинкремент (IDENTITY (1,1)), при вызове усечения счетчик первичного ключа таблицы сбрасывается в 1.
3) Добавьте строки в таблицу через Entity Framework, а затем вызовите SaveChanges(). Из-за усечения таблицы первичный ключ новой строки равен 1. После создания строки EntityFramework запрашивает у базы данных значения строк, создает новый объект, заполняет значения в объекте и добавляет объект в его локальное представление.,
Поскольку в контексте уже был другой объект с первичным ключом = 1, сохраненный в его локальном представлении (из шага 1), возникает исключение, когда он пытается добавить второй объект с тем же первичным ключом в локальное представление.
Чтобы избежать этой ситуации, EntityFramework должен быть синхронизирован с содержимым базы данных перед выполнением новых операций.
В моем случае я должен был это исправить, позвонив:
Context.MyTableEntities.Local.Clear();
Context.SaveChanges();
Таким образом, сущности были удалены в первую очередь, и контекст был рассказан об этом. Затем я обрезал таблицу с помощью SQL-запроса, чтобы сбросить счетчик автоматического приращения.
Так как объекты сначала были удалены из локального представления, а затем было выполнено усечение таблицы (таким образом, он сбрасывает счетчик автоматического приращения), конфликтов первичных ключей удалось избежать.
Надеюсь, это поможет.