Почему Entity Framework обнаруживает изменения свойств, которые были изменены, но сброшены? - PullRequest
3 голосов
/ 30 ноября 2011

Если я изменяю свойство объекта POCO, но сбрасываю его, EntityFramework все равно говорит, что есть изменения.

Property "Name": Value "Test" (original value) 
              -> Value "Test123" (value changed by UI) 
              -> Value "Test" (value changed by UI to original value)

Записи, которые были изменены:

var objectStateEntries = 
    _db.ObjectStateManager.GetObjectStateEntries(
        EntityState.Added | 
        EntityState.Deleted | 
        EntityState.Modified);

Как вы справляетесь с этим делом?

Ответы [ 2 ]

7 голосов
/ 30 ноября 2011

Если все ваши свойства virtual Entity Framework автоматически создаст динамический прокси вашего POCO по умолчанию. Если я не ошибаюсь, отслеживание изменений в этом случае основано на установщиках свойств этого динамического объекта, примерно так:

private string _name;
public string Name
{
    // ...
    set
    {
        // if (_name != value) such a check probably does not happen
        {
            _name = value;
            MarkPropertyAsModified(...);
        }
    }
}

Таким образом, нет сравнения с исходным значением, а только с текущим значением свойства. Если это значение изменяется, свойство помечается как измененное, независимо от того, вернули ли вы его обратно к исходному значению.

( Редактирование и исправление предыдущего абзаца: Свойство помечается как измененное, если вызывается установщик, независимо от того, присвоено ли то же самое или измененное значение. Спасибо Брэду Томасу и его комментарию ниже !)

Вы можете избежать создания динамических прокси, отключив это в параметрах контекста:

objectContext.ContextOptions.ProxyCreationEnabled = false;

Обнаружение изменений теперь будет зависеть от создания снимка, что означает, что EF сравнивает исходное значение (сохраненное в снимке в контексте объекта) с текущим значением , когда обнаружение изменения вызывается . Это больше не происходит в установщиках свойств, но внутри некоторых функций Entity Framework, например в SaveChanges. В вашей ситуации это будет означать, что при вызове SaveChanges исходное значение (снимок) и текущее значение будут одинаковыми, поскольку вы сбросили изменение. По сути, EF не заметил, что вы дважды изменили свойство, и считает его неизменным.

Имейте в виду, что отключение создания прокси - если вы делаете это глобально, например, в конструкторе контекста - является потенциально глубоким изменением для вашего приложения. Для правильной работы у вас может быть код, который зависит от динамических прокси, а также может сильно влиять на производительность в различных ситуациях. Динамические прокси существуют для быстрого отслеживания изменений. Отслеживание изменений на основе моментальных снимков выполняется намного медленнее.

0 голосов
/ 01 мая 2012

В случае динамических прокси-объектов после изменения значения свойства контекст помечает его как измененный.

...