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
на ваш запрос - внутри метода репозитория, а не на уровне сервиса.