EF5 Секреты метода DetectChanges — II

Отключение автоматического определения изменений

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

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

В данном примере каждый вызов метода Add() (так же будет и с Attach()) дергает метод DetectChanges() и если постов очень много, то такая запись может стать очень дорогой. Для избегания накладных расходов в этом случае, стоит отключить автоматическое обнаружение изменений.

Использование try\finally гарантирует, что автоматическое обнаружение изменений всегда включится обратно.

Подробнее

EF5 Секреты метода DetectChanges — I

Секреты в том смысле, что это вещи, которые захочется знать EF гику.

Отслеживание изменений при работе с Entity Framework обычно не требует от разработчика каких-то особенных действий или размышлений. Тем не менее, отслеживание изменений и работа метода DetectChanges() является ключевым моментом и основной дилеммой между легкостью использования и производительностью. По этой причине было бы неплохо знать как именно работает метод DetectChanges(), что при этом происходит, для того чтобы принимать осознанные решения в случае модификации поведения при получении изменений, если ваше приложение ведет себя не так как задумывалось.

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

 

Проблема определения изменений

Большинство современных приложений, я думаю, используют простые POCO объекты, которые не знают о методе своего сохранения в базу данных. При работе с POCO объектами используется алгоритм сравнения данных, основанный на первоначальном «снимке» объекта (Snapshot). Это значит, что в самом объекте POCO нет никакой логики, которая позволяла бы отслеживать изменения и уведомлять об этом контекст БД.

Подробнее

EF5 Особенности использования прокси отслеживания изменений

В прошлом посте я рассказал о различных типах данных, которые поддерживаются в EF, но какой же тип выбрать для использования. На мой взгляд, исходя из указанных данных, вытекает следующее:

  • Не стоит использовать наследование от EntityObject или IPOCO вообще. Нет никаких плюсов в их использовании.
  • Используйте POCO сущности и сделайте навигационные свойства виртуальными, чтобы можно было получить плюсы ленивой загрузки.
  • Если вы сериализуете свои сущности, тогда стоит подумать о том, чтобы выключить прокси и отказаться от ленивой загрузки, так как восстановление объектов может быть проблематичным.

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

Подробнее

EF5 типы поддерживаемых сущностей

В результате копания во внутренностях EntityFramework я наткнулся на change-tracking proxies, которые с одной стороны натолкнули меня на мысль создания self-tracking objects для обычных объектов с помощью PostSharp. Однако перед началом рассказа о прокси-объектах изменения состояния, стоит рассказать о других классах объектов поддерживаемых  EF. Далее идет их описание в хронологическом порядке, как они был реализованы/введены во фреймворк.

Сущности, наследуемые от EntityObject

Единственный тип сущностей, поддерживаемый в самой первой предварительно реализации EF, были классы наследуемые от класса EntityObject, входящего в пространство имен EF. Наследование от EntityObject предоставляло ряд сервисов, таких как:

  • отслеживание изменений состояния свойств класса,
  • управление связями между сущностями,
  • работа с первичными и вторичными ключами.

Существование такого базового класса позволяло весьма эффективно EF управлять сущностями.

Минусом такого подхода, и очень БОЛЬШИМ минусом , было то, что бизнес-объекты и слой доступа данных (EF) были связаны более чем тесно, к тому же это нарушает принцип persistence-ignorance, т.е. объект не должен знать и завязываться на то как именно он сохраняется. Это была одна из причин, по которой я долгое время игнорировал и не стремился использовать в работе Entity Framework. К тому же, на практике, наследование от EntityObject делало работу с бизнес-объектами сложнее и полной специфичного для EF кода.

Сущности, наследуемые от EntityObject поддерживаются EF1 и EF4, но не DbContext и CodeFirst, которые были введены в версиях EF4.x.

Подробнее