Мне трудно определить лучший способ справиться с этим ... С помощью Entity Framework (и L2S) запросы LINQ возвращают IQueryable. Я читал различные мнения о том, должен ли DAL / BLL возвращать IQueryable, IEnumerable или IList. Предполагая, что мы используем IList, запрос выполняется немедленно, и этот контроль не передается следующему уровню. Это облегчает юнит-тестирование и т. Д. Вы теряете возможность уточнять запрос на более высоких уровнях, но вы можете просто создать другой метод, который позволит вам уточнить запрос и при этом вернуть IList. И есть еще много плюсов / минусов. Пока все хорошо.
Теперь идет Entity Framework и ленивая загрузка. Я использую объекты POCO с прокси в .NET 4 / VS 2010. На уровне представления я делаю:
foreach (Order order in bll.GetOrders())
{
foreach (OrderLine orderLine in order.OrderLines)
{
// Do something
}
}
В этом случае GetOrders () возвращает IList, поэтому он выполняется непосредственно перед возвратом в PL. Но в следующем foreach у вас ленивая загрузка, которая выполняет несколько SQL-запросов по мере получения всех строк OrderLines. Таким образом, в основном, PL выполняет запросы SQL «по требованию» на неправильном уровне.
Есть ли разумный способ избежать этого? Я мог бы отключить ленивую загрузку, но тогда какой смысл иметь эту «особенность», которой все жаловались, что EF1 не имел? И я признаю, что это очень полезно во многих сценариях. Итак, я вижу несколько вариантов:
- Каким-то образом удалите все ассоциации в сущностях и добавьте методы для их возврата. Это идет вразрез со стандартным поведением EF / генерацией кода и усложняет выполнение некоторых составных запросов (из нескольких сущностей) LINQ. Это похоже на шаг назад. Я голосую нет.
- Если в любом случае у нас отложенная загрузка, что затрудняет юнит-тестирование, то проделайте весь путь и верните IQueryable. Вы будете иметь больше контроля над слоями. Я все еще не думаю, что это хороший вариант, потому что IQueryable связывает вас с L2S, L2E или с вашей собственной полной реализацией IQueryable. Ленивая загрузка может запускать запросы «по требованию», но не привязывает вас к какому-либо конкретному интерфейсу. Я голосую нет.
- Отключить ленивую загрузку. Вам придется обрабатывать ваши ассоциации вручную. Это может быть с нетерпением загрузки .Include (). Я голосую "за" в некоторых конкретных случаях.
- Сохраняйте IList и ленивую загрузку. Я голосую "за" во многих случаях, только из-за проблем с другими.
Есть ли другие варианты или предложения? Я не нашел вариант, который действительно убеждает меня.