Несоответствия DbContext.ChangeTracker, DbContext.Entry () - PullRequest
1 голос
/ 17 ноября 2011

Под отладчиком у меня есть случай, когда DbContext.ChangeTracker.Entry(e) возвращает запись с State из Detached.Когда при поиске e я перечисляю результаты DbContext.ChangeTracker.Entries() и записи базового ObjectContext, я нахожу запись с State из Unchanged (ожидается).

Что такоечто происходит?

Вот некоторые дополнительные сведения:

  • с использованием сущностей POCO.
  • изменение Отслеживание включено
  • создание прокси отключено
  • отложенная загрузка отключена
  • проблема не возникает при первом сохранении объекта (например, добавление в контекст);происходит, когда старый объект попадает в контекст, а затем пытается внести в него изменения.Это агрегированный корень со многими «ссылочными» сущностями, которые не должны изменяться
  • Equals переопределяется на сущностях и IEquatable<T> реализован.Этот код генерируется T4.
  • Я использую стандартную реализацию репозитория, которая декларативно настроена на генерацию правил для сохранения (например, должны ли объекты быть добавлены, присоединены / изменены, присоединены / неизменны.это в правильном порядке. Например, агрегатный корень добавляется / присоединяется последним, потому что его присоединение сначала приводит к изменению других сущностей в измененном состоянии (добавление тех первых как неизмененных предотвращает это).

1 Ответ

0 голосов
/ 03 февраля 2015

(Ответ на вопрос редактируется. Преобразован в вики-ответ сообщества. См. Вопрос без ответов, но проблема решена в комментариях (или расширена в чате) )

ОП написал:

Я «решил» проблему, но я все еще хочу знать, что происходит, потому что мое решение ничего не делает для устранения основной причины. Мое "решение" ищет сущность в трекере изменений (я также просматривал через context.Entry() и context.Set().Local - когда я делаю это с этим кодом (я сделал это в виде цикла вместо LINQ, чтобы я мог установить точки останова) ), работает:

private DbEntityEntry GetChangeTrackedEntry(IEntity mine, Type type)
    {
        foreach (var en in context.ChangeTracker.Entries())
        {
            if (en.Entity.GetType() != type)
                continue;
            if (((IEntity)en.Entity).Id != mine.Id)
                continue;
            return en;
        }

        return null;
    }

Когда я пытаюсь найти объект (с помощью трекера изменений, набора и т. Д.), Используя непосредственно мое, именно тогда я получаю отдельный случай.

Я подумал, что, возможно, были случаи, когда EF использовал ReferenceEquals, но комментарий @ Ladislav может указывать на что-то не так с реализацией Equals.

Если у кого-то есть дополнительное объяснение, он может отредактировать его в ответе этого вики-сообщества.

...