Если вы говорите о динамических прокси в EF, то можно различить два разных типа:
- Прокси для ленивой загрузки
- Прокси для отслеживания изменений
Обычно прокси отслеживания изменений также может служить прокси для отложенной загрузки. Обратное неверно. Это связано с тем, что требования к прокси-серверам отслеживания изменений выше, особенно все свойства, а также скалярные свойства, должны быть virtual
. Для отложенной загрузки достаточно, чтобы навигационные свойства были virtual
.
Тот факт, что прокси-сервер отслеживания изменений всегда позволяет использовать ленивую загрузку, является основной причиной, по которой DbContext имеет этот флаг конфигурации:
DbContext.Configuration.LazyLoadingEnabled
Этот флаг по умолчанию имеет значение true. Установка false
отключает отложенную загрузку, даже если созданы прокси. Это особенно важно, если вы работаете с прокси-серверами отслеживания изменений, но не хотите использовать их также для отложенной загрузки.
Опция ...
DbContext.Configuration.ProxyCreationEnabled
... полностью отключает создание прокси - для отслеживания изменений и отложенной загрузки.
Оба флага имеют смысл только в том случае, если ваши классы сущностей соответствуют требованиям для создания прокси отслеживания изменений или отложенной загрузки.
Теперь вы знаете цель динамической отложенной загрузки прокси. Итак, зачем использовать динамические прокси отслеживания изменений?
На самом деле единственная причина, по которой я знаю, это производительность . Но это очень веская причина. Сравнивая отслеживание изменений на основе снимков с отслеживанием изменений на основе прокси-серверов, разница в производительности огромна - по моим измерениям коэффициент от 50 до 100 является реалистичным (взят из метода, который требовал около одного часа для 10000 циклов с отслеживанием изменений на основе снимков и от 30 до 60 секунд после того, как все свойства виртуальные, чтобы включить прокси отслеживания изменений). Это становится важным фактором, если у вас есть приложение, которое обрабатывает и изменяет многие (скажем, более 1000) сущностей. В веб-приложении, где вы, возможно, выполняете операции «Создать / Изменить / Удалить» только с отдельными объектами в веб-запросе, эта разница не имеет большого значения.
Практически во всех ситуациях вы можете использовать энергичную или явную загрузку для достижения той же цели, если вы не хотите работать с ленивыми загрузочными прокси. Производительность для отложенной загрузки на основе прокси-сервера или явной загрузки не на основе прокси-сервера одинакова, поскольку при загрузке свойств навигации в основном происходит один и тот же запрос - в первом случае прокси-сервер выполняет запрос, во втором - ваш рукописный код. Таким образом, вы можете жить без ленивой загрузки прокси, не теряя многого.
Но если вы хотите, чтобы разумная производительность обрабатывала много, у многих сущностей нет альтернативы изменению прокси-серверов отслеживания - кроме использования EntityObject
производных сущностей в EF 4.0 (не вариант в EF 4.1, потому что это запрещено при использовании DbContext
) или вообще не используете Entity Framework.
Редактировать (май 2012 г.)
Тем временем я узнал, что есть ситуации, когда смена прокси отслеживания не быстрее или даже хуже по сравнению с отслеживанием на основе снимка.
Из-за этих сложностей при использовании прокси-серверов отслеживания изменений предпочтительным способом является использование отслеживания изменений на основе моментальных снимков по умолчанию и осторожное использование прокси-серверов (после выполнения некоторых тестов) только в ситуациях, когда требуется высокая производительность и когда они оказываются быстрее чем отслеживание изменений на основе снимков.