Я знаю, что эти вопросы заданы раньше, я начну с перечисления некоторых из них (тех, которые я читал до сих пор):
- IEnumerable vs IQueryable
- Список, IList, IEnumerable, IQueryable, ICollection, который является наиболее гибким типом возврата?
- Возврат IEnumerable <T> vs. IQueryable <T>
- IEnumerable <T> как тип возврата
- https://stackoverflow.com/info/2712253/ienumerable-and-iqueryable
- Просмотры с бизнес-логикой и кодом
- WPF IEnumerable <T> vs IQueryable <T> как DataSource
- IEnumerable <T> VS IList <T> VS IQueryable <T>
- Какой интерфейс должен вернуть мой сервис? IQueryable, IList, IEnumerable?
- Должен ли я возвращать IEnumerable <T> или IQueryable <T> из моего DAL?
Как вы можете видеть, есть некоторые большие ресурсы на SO только по этому вопросу, но есть один вопрос/раздел вопроса, который я все еще не уверен в том, что прочитал все это.
В первую очередь меня интересует вопрос IEnumerable vs IQueryable и, более конкретно, связь между DAL и его потребителями.
Я нашел разные мнения относительно двух интерфейсов, которые были замечательными. Тем не менее, я обеспокоен последствиями возврата DAL IQueryable. Насколько я понимаю, IQueryable предлагает/подразумевает, что под капотом есть Linq Provider. Это касается номера один - что, если 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 наиболее рекомендуемым во всех вопросах, которые я проверил, но как насчет требования отложенных нагрузок для доступа к datacontext? Как я понимаю, если ваша функция возвращает IEnumerable, но вы возвращаете IQueryable, IQueryable полагается на базовый datacontext. Поскольку результат на этом этапе фактически является выражением, и ничего не было принесено в память, вы не можете гарантировать, что потребитель DAL/функция будет выполнять запрос или когда. Так я должен держать экземпляр контекста, что результаты были получены из доступных каким-то образом? Это как/почему шаблон Unit of Work вступает в игру?
Сводка вопросов для ясности (выполнил поиск "?"...):
- Если вы используете IQueryable как возвращаемый тип, слишком ли вы слишком тесно связываете свою пользовательскую логику/бизнес-логику с поставщиками Linq?
- Является ли использование расширения AsQueryable() хорошей идеей, если вам вдруг нужно вернуть данные из источника, не связанного с Linq?
- У кого-нибудь есть хорошая ссылка, описывающая, как, например, работает преобразование стандартного списка в AsQueryable, что он на самом деле делает?
- Как вы обрабатываете дополнительные требования фильтрации, поставляемые бизнес-логикой, к вашему DAL?
- Кажется, что отложенная загрузка IEnumerable и IQueryable подлежит поддержанию базового провайдера, следует ли использовать шаблон Unit of Work или что-то еще для этого?
Большое спасибо!