Разрешение идентификаторов, управление состоянием и отслеживание изменений (платформа Entity Framework)

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

Отслеживание изменений

Сведения об отслеживании изменений графа объектов сохраняются в объектах ObjectStateEntry, которые создаются контекстом объекта ObjectContext для каждого присоединенного объекта. Объекты ObjectStateEntry хранят следующие сведения сущностей:

  • Ключ EntityKey, который определяет идентификатор сущности.

  • Состояние EntityState для объекта.

  • Сведения о связанных объектах.

  • Имя набора сущностей.

  • Значения CurrentValues и OriginalValues свойств сущности (объекты в состоянии Added не содержат исходные значения).

  • Имена измененных свойств сущности.

Чтобы определить, было ли изменено значение свойства между вызовами метода SaveChanges, необходимо выполнить запрос коллекции имен измененных свойств, которая возвращается методом GetModifiedProperties.

Bb896269.note(ru-ru,VS.100).gifПримечание
Если используются сущности POCO без посредников для отслеживания изменений, перед вызовом метода GetModifiedProperties необходимо вызвать метод DetectChanges.

При отсоединении сущности соответствующий объект ObjectStateEntry удаляется из контекста объекта.

Объекты ObjectStateEntry управляются ObjectStateManager. Для каждого контекста объекта существует один экземпляр ObjectStateManager. Чтобы получить объект ObjectStateEntry для указанной сущности, воспользуйтесь одним из следующих методов для ObjectStateManager, TryGetObjectStateEntry, GetObjectStateEntry или GetObjectStateEntries.

Контекст объекта уведомляется об изменениях свойств созданных Entity Framework сущностей и прокси-объектов POCO, отслеживающих изменения по мере их внесения, он обновляет состояние объектов и значения свойств в ObjectStateEntry. Модель отчета об изменениях предполагает выполнение с помощью интерфейса IEntityChangeTracker отчета об отложенном изменении свойства, задание свойства и последующий отчет о завершении изменения. ObjectStateEntry управляет сущностями POCO без прокси-объектов, отслеживающих изменения, и объектами сложного типа иным образом. Дополнительные сведения см. в разделе Отслеживание изменений в сущностях POCO (платформа Entity Framework).

Контекст объекта использует сведения из объектов ObjectStateEntry для хранения данных в источнике данных. Дополнительные сведения см. в разделах Сохранение изменений и управление параллелизмом (платформа Entity Framework) и Как выполнять правила бизнес-логики при сохранении изменений (платформа Entity Framework).

Разрешение идентификаторов и параметры слияния

Entity Framework сохраняет в кэше только один экземпляр объекта с определенным ключом сущности. Объекты EntityKey являются неизменяемыми объектами, которые представляют идентификаторы объектов. Ключи сущности используются для разрешения идентификаторов в контексте объекта. Дополнительные сведения см. в разделе Работа с ключами сущностей (платформа Entity Framework). Если сущность с тем же идентификатором уже отслеживается, выполняется слияние данных, поступающих из источника данных, и данных, уже содержащихся в диспетчере состояния, в соответствии с параметром MergeOption запроса.

В следующей таблице приведены возможные параметры слияния.

Элемент Описание

AppendOnly

Объекты, которые не существуют в контексте объекта, присоединяются к контексту. Если объект уже находится в контексте, текущие и исходные значения свойств объекта в записи не переписываются значениями из источника данных. Состояние записи объекта и состояние свойств объекта в записи не меняется. Параметр AppendOnly является параметром слияния по умолчанию.

OverwriteChanges

Объекты, которые не существуют в контексте объекта, присоединяются к контексту. Если объект уже находится в контексте, текущие и исходные значения свойств объекта в записи переписываются значениями из источника данных. Состоянию записи объекта присваивается значение Unchanged, а свойства, отмеченные как измененные, отсутствуют.

PreserveChanges

Объекты, которые не существуют в контексте объекта, присоединяются к контексту.

Если состояние сущности имеет значение Unchanged, текущие и исходные значения в записи переписываются значениями из источника данных. Значение состояния сущности остается равным Unchanged, а свойства, которые отмечены как измененные, отсутствуют.

Если состояние сущности имеет значение Modified, текущие значения измененных свойств объекта не переписываются значениями из источника данных. Исходные значения свойств, которые не были изменены, переписываются значениями из источника данных.

В .NET Framework версии 4 Entity Framework выполняет сравнение текущих значений свойств, которые не были изменены, со значениями, которые были возвращены из источника данных. Если значения отличаются, свойство отмечается как измененное.

В .NET Framework версии 3.5 SP1 Entity Framework не отмечает свойство как измененное, даже если в источнике данных указано другое значение.

При вызове метода SaveChanges в источнике данных сохраняются только измененные свойства.

Чтобы сохранить поведение из версии 3.5 с пакетом обновления 1 (SP1), присвойте параметру UseLegacyPreserveChangesBehavior значение true. Параметр PreserveChanges может использоваться для разрешения исключений оптимистичного параллелизма при сохранении изменений в локальном контексте. Дополнительные сведения см. в разделе Сохранение изменений и управление параллелизмом (платформа Entity Framework).

NoTracking

Объекты обслуживаются в состоянии Detached и не отслеживаются экземпляром ObjectStateManager. Однако сущности, созданные Entity Framework , и сущности POCO с прокси-объектами сохраняют ссылку на контекст объекта для содействия загрузке связанных объектов.

Состояние сущности

Контексту объекта необходимы сведения о состоянии объекта для сохранения изменений в источнике данных. Данные EntityState сохраняются в объектах ObjectStateEntry. Методы SaveChanges контекста объекта ObjectContext обрабатывают сущности, присоединенные к контексту, и обновляют источник данных в соответствии со значением EntityState каждого из объектов. Дополнительные сведения см. в разделе Создание, добавление, изменение и удаление объектов (платформа Entity Framework). В следующей таблице представлены возможные состояния объекта.

Элемент Описание

Added

Объект является новым, он был добавлен в контекст объекта без вызова метода SaveChanges. После сохранения изменений состояние объекта меняется на Unchanged. У объектов в состоянии Added отсутствуют исходные значения в ObjectStateEntry.

Deleted

Объект был удален из контекста объекта. После сохранения изменений состояние объекта меняется на Detached.

Detached

Объект существует, но не отслеживается. Сущность находится в этом состоянии сразу после создания и до добавления в контекст объекта. Сущность также находится в этом состоянии после ее удаления из контекста с помощью вызова метода Detach или в случае ее загрузки с помощью NoTrackingMergeOption. Экземпляр ObjectStateEntry, который связан с объектами в состоянии Detached, отсутствует.

Modified

Одно из скалярных свойств объекта было изменено, а метод SaveChanges не был вызван. В сущностях POCO без посредников, отслеживающих изменения, состояние измененных свойств при вызове метода DetectChanges меняется на Modified. После сохранения изменений состояние объекта меняется на Unchanged.

Unchanged

Объект не был изменен с момента присоединения к контексту или с момента последнего вызова метода SaveChanges.

Состояние объектов в пределах контекста объекта управляется ObjectStateManager. Чтобы определить состояние объекта, воспользуйтесь методом ObjectStateManager: TryGetObjectStateEntry, GetObjectStateEntry или GetObjectStateEntries. Свойство State объекта ObjectStateEntry определяет состояние объекта.

См. также

Основные понятия

Работа с ключами сущностей (платформа Entity Framework)