Я знаю, что эти вопросы задавались ранее, я начну с перечисления нескольких из них (те, которые я читал до сих пор):
Как вы можете видетьЕсть несколько замечательных ресурсов по SO только на эту тему, но есть один вопрос / раздел вопроса, который я до сих пор не уверен, прочитав их все до конца.
Меня больше всего интересует IEnumerable vsIQueryable вопрос, а точнее, связь между DAL и потребителями .
Я нашел различные мнения относительно двух интерфейсов, которые были великолепны.Тем не менее, я обеспокоен последствиями возвращения DAL IQueryable.Насколько я понимаю, IQueryable предлагает / подразумевает, что под капотом находится провайдер Linq.Это проблема номер один - что, если DAL вдруг потребует данные из источника, не предоставленного Linq?Следующее будет работать, но это скорее хак?
public static IQueryable<Product> 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<Product> results = new List<Product> { new Product() };
return results.AsQueryable();
}
Так что я могу использовать расширение AsQueryable (), хотя я не признаю, что точно знаю, что это делает?Я всегда представляю IQueryables как базовые деревья выражений, которые мы можем добавлять по мере необходимости, пока мы не будем готовы выполнить нашего запроса и извлечь результаты.
Я мог бы исправить это, изменив возвращаемый результаттип функции для IEnumerable.Затем я могу вернуть IQueryable из функции, потому что она наследует IEnumerable, и я могу сохранить отложенную загрузку.Что я теряю, так это возможность добавлять к выражению запроса:
var results = SomeClass.GetAll().Where(x => x.ProductTypeId == 5);
При возврате IQueryable, насколько я понимаю, это просто добавит выражение.При возврате IEnumerable, несмотря на сохранение отложенной загрузки, выражение должно быть оценено, чтобы результаты были перенесены в память и пронумерованы для фильтрации неправильных ProductTypeIds.
Как другие люди обходят это?
- Предоставить больше функций в DAL - GetAllByProductType, GetAllByStartDate, ... и т. Д.
Предоставить перегрузку, которая принимает предикаты?т.е.
public static IEnumerable<Product> GetAll(Predicate<Product> predicate)
{
List<Product> results = new List<Product> { new Product() };
return results.Where(x => predicate(x));
}
Одна последняя часть (извините, я знаю, очень длинный вопрос!).
Я считаю, что IEnumerable является наиболее рекомендуемым во всех вопросах, которые япроверил, но как быть с требованием отсроченных загрузок для доступности текста данных?Насколько я понимаю, если ваша функция возвращает IEnumerable, но вы возвращаете IQueryable, IQueryable зависит от базового текста данных.Поскольку результат на этом этапе на самом деле является выражением и ничего не было занесено в память, вы не можете гарантировать, что потребитель DAL / функции будет выполнять запрос, ни когда.Так должен ли я сохранять экземпляр контекста, из которого были получены результаты, каким-то образом?Это как / почему шаблон единицы работы входит в игру?
Краткое изложение вопросов для ясности (выполнил поиск "?" ...):
- При использованииIQueryable в качестве типа возврата, слишком ли сильно вы связываете свой пользовательский интерфейс / бизнес-логику с провайдерами Linq?
- Является ли использование расширения AsQueryable () хорошей идеей, если вам вдруг нужно вернуть данные из источника, не предоставленного Linq
- У кого-нибудь есть хорошая ссылка, описывающая, как, например, преобразование стандартного списка в AsQueryable работает, что он на самом деле делает?
- Как вы справляетесь с дополнительными требованиями к фильтрации, предоставляемыми бизнес-логикой для вашего DAL?
- Кажется, что отложенная загрузка IEnumerable и IQueryable зависит от поддержки основного провайдера. Должен ли я использовать шаблон Unit of Work или что-то еще для этого?
Заранее большое спасибо!