Ошибка 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-запроса, чтобы сбросить счетчик автоматического приращения.

Так как объекты сначала были удалены из локального представления, а затем было выполнено усечение таблицы (таким образом, он сбрасывает счетчик автоматического приращения), конфликтов первичных ключей удалось избежать.

Надеюсь, это поможет.

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