EF4: Почему создание прокси должно быть включено, если включена отложенная загрузка?

У меня есть проект, структурированный следующим образом: .Persistence -> .Repo -> .Services -> .Controllers -> MVC3 App.

Каждый уровень имеет соответствующую сборку с интерфейсами, а также есть некоторые другие сборки, такие как.Entities,.ViewModels и общие сборки кода.

Постоянство - содержит текстовый код EF4 (сначала код) и ссылку на EF4.3. Существует фабрика для создания контекста с именем GetContext(), и эта фабрика реализует IDisposable. Это НЕ одиночка, потому что я подумал, что именно то, что Виндзор сделает для меня с LifestyleSingleton().
Репо - содержит репозитории, реализующие шаблон репозитория и спецификации ( http://huyrua.wordpress.com/2010/07/13/entity-framework-4-poco-repository-and-specification-pattern/).

Другие слои говорят сами за себя...

Вопросы:
1. Почему создание прокси должно быть включено, если включена отложенная загрузка?
2. Если я хочу установить lazyloading = false, могу ли я привести свой IEnumerable в слое Service к ObjectQuery, чтобы использовать там.Include()?

1 ответ

Решение

Почему создание прокси должно быть включено, если включена отложенная загрузка?

Потому что ленивая загрузка с POCO зависит от создания прокси. Без прокси ленивая загрузка не работает. Поэтому комбинация ProxyCreationEnabled = false а также LazyLoadingEnabled = true не имеет смысла. Обратная комбинация имеет смысл, если вы хотите работать с прокси-серверами отслеживания изменений, но не хотите использовать отложенную загрузку.

Если я хочу установить lazyloading = false, могу ли я привести свой IEnumerable в слое Service к ObjectQuery, чтобы использовать там.Include()?

Это зависит от того, что ваш IEnumerable<T> действительно есть. Если это результат ToList() тогда нет (потому что List<T> это реализация IEnumerable<T> но не из IQueryable<T>.). Если вы просто вернете IQueryable<T> как IEnumerable<T> вы, вероятно, можете привести к IQueryable<T>, (В EF 4.3 вы бы использовали IQueryable<T> или же DbQuery<T> скорее, чем ObjectQuery<T>.)

Но imho необходимость такого приведения указывает на то, что что-то не так в вашей архитектуре. С помощью Include является модификацией запроса. Если вашему сервисному слою разрешено изменять запросы, ваш репозиторий должен вернуть IQueryable<T> - этот тип предназначен для построения и изменения запросов.

Если ваш репозиторий не должен возвращаться IQueryable<T> Вы должны передать выражение или спецификацию в методы репозитория, которые используются для добавления Include на ваш запрос - внутри метода репозитория, а не на уровне сервиса.

Другие вопросы по тегам