Ошибка 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();
    }

person Tuğrul Alpdoğan    schedule 26.07.2012    source источник
comment
С каким методом это происходит (например, Add(T entity), Attach(T entity))? А можешь выложить трассировку стека?   -  person Major Productions    schedule 26.07.2012


Ответы (2)


Вы уверены, что добавляете разные сущности в EF? Внутреннее исключение указывает, что AcceptChanges() не работает, потому что текущий объект, который вы пытаетесь добавить, имеет общий ключ с объектом, который уже отслеживается.

Дополнительные сведения о AcceptChanges() см. по адресу: http://msdn.microsoft.com/en-us/library/system.data.objects.objectstateentry.acceptchanges.aspx

person Major Productions    schedule 26.07.2012
comment
Этим способом? Context.ObjectStateManager.GetObjectStateEntry(entity).AcceptChanges(); - person Tuğrul Alpdoğan; 26.07.2012

У меня была эта проблема, и я обнаружил, что выполнял следующие операции, из-за чего EntityFramework не синхронизировался с данными в базе данных:

1) Сделайте запрос к строкам таблицы через контекст Entity Framework. При этом контекст EntityFramework сохраняет копию этих объектов в своем локальном представлении.

2) Сократите таблицу с помощью SQL-запроса (поэтому контекст Entity Framework не знает, что это произошло. Объекты по-прежнему находятся в своем локальном представлении, даже если они были усечены в базе данных). Поскольку первичный ключ таблицы автоматически увеличивается (IDENTITY (1,1)), вызов усечения сбрасывает счетчик первичного ключа таблицы на 1.

3) Добавьте строки в таблицу через Entity Framework, а затем вызовите SaveChanges(). Из-за усечения таблицы первичный ключ новой строки равен 1. После создания строки EntityFramework запрашивает базу данных для значений строки, создает новую сущность, заполняет значения в сущности и добавляет сущность в свое локальное представление. .

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

Чтобы избежать этой ситуации, Entity Framework должен синхронизироваться с содержимым базы данных перед выполнением новых операций.

В моем случае мне пришлось исправить это, позвонив:

Context.MyTableEntities.Local.Clear();
Context.SaveChanges();

Итак, Сущности были удалены первыми, и об этом было сказано в контексте. Затем я обрезал таблицу с помощью SQL-запроса, чтобы сбросить счетчик автоматического увеличения.

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

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

person sboisse    schedule 05.11.2014