Я знаю, что эти вопросы задавались раньше, я начну с перечисления некоторых из них (тех, которые я читал до сих пор):
Как видите, есть отличные ресурсы только по SO по этой теме, но есть один вопрос / Я до сих пор не уверен, прочитал ли я все это полностью.
Меня в первую очередь беспокоит вопрос IEnumerable и IQueryable, и, в частности, связь между DAL и его ] потребителей .
Я нашел разные мнения относительно двух интерфейсов, и они оказались великолепными. Однако меня беспокоят последствия возврата IQueryable из DAL. Насколько я понимаю, IQueryable предполагает / подразумевает, что под капотом есть поставщик Linq. Это проблема номер один - что, если DAL внезапно потребует данные из источника, не предоставленного Linq? Следующее будет работать, но это скорее хакерская игра?
public static IQueryable GetAll()
{
// this function used to use a L2S context or similar to return data
// from a database, however, now it uses a non linq provider
// simulate the non linq provider...
List results = new List { new Product() };
return results.AsQueryable();
}
Итак, я могу использовать расширение AsQueryable (), хотя я не признаю, что точно знаю, что оно делает? Я всегда представляю IQueryables как базовые деревья выражений, которые мы можем добавлять по мере необходимости, пока мы не будем готовы выполнить наш запрос и получить результаты.
Я мог бы исправить это, изменив возвращаемый тип функцию в IEnumerable. Затем я могу вернуть IQueryable из функции, потому что он наследует IEnumerable, и я могу сохранить отложенную загрузку. Я теряю возможность добавления к выражению запроса:
var results = SomeClass.GetAll().Where(x => x.ProductTypeId == 5);
При возврате IQueryable, насколько я понимаю, это просто добавило бы выражение. При возврате IEnumerable, несмотря на сохранение отложенной загрузки, выражение должно быть оценено, чтобы результаты были занесены в память и пронумерованы, чтобы отфильтровать неверные ProductTypeIds.
Как другие люди обойти это?
Предоставить перегрузку, которая принимает предикаты? то есть
общедоступный статический IEnumerable GetAll (предикат Predicate )
{
Список результаты = новый Список {новый продукт ()};
вернуть результаты. Где (x => predicate (x));
}
И последнее (извините, я знаю, очень длинный вопрос!).
Я обнаружил, что IEnumerable является наиболее рекомендуемым из всех проверенных мной вопросов, но как насчет требования отложенной загрузки для доступности контекста данных? ? Насколько я понимаю, если ваша функция возвращает IEnumerable, но вы возвращаете IQueryable, IQueryable зависит от базового контекста данных. Поскольку результат на этом этапе фактически является выражением и ничего не было занесено в память, вы не можете гарантировать, что потребитель DAL / функции будет выполнить запрос, ни когда. Итак, должен ли я каким-то образом сохранять доступным экземпляр контекста, из которого были получены результаты? Это как / почему используется шаблон «Единица работы»?
Сводка вопросов для ясности (выполнялся ли поиск «?» ...):
Заранее большое спасибо!