2010-04-20 2 views
15

Я видел много людей, которые говорили о IQueryable, и я не совсем понял, о чем идет речь. Я всегда работаю с общими List и обнаруживаю, что они очень богаты тем, как вы можете «запрашивать» их и работать с ними, даже запускать запросы LINQ против них.Что такое большое дело с IQueryable?

Мне интересно, есть ли веские причины, чтобы начать рассмотрение другой коллекции по умолчанию в моих проектах.

+0

'IQueryable' принципиально отличается от' list' - оба имеет свою область применения. –

ответ

42

Интерфейс IQueryable позволяет определять части запроса у удаленного провайдера LINQ (как правило, для базы данных, но не обязательно) в несколько этапов и с отсроченным исполнением.

E.g. ваш уровень базы данных может определить какое-либо ограничение (например, на основе разрешений, безопасность - независимо), добавив в ваш запрос предложение .Where(x => x.......). Но пока это не выполняется. вы не извлекаете 150'000 строк, соответствующих этим критериям.

Вместо этого вы передаете интерфейс IQueryable на следующий уровень, бизнес-уровень, где вы можете добавлять дополнительные требования и где предложения к вашему запросу - опять же, ничего не выполняется, пока вы еще не выкидываете 80'000 ваших 150'000 строк, которые вы получили - вы просто определяете дополнительные критерии запроса.

И слой UI может делать то же самое, например. основанный на вводе пользователя в форме или что-то в этом роде.

Магия в том, что вы передаете интерфейс IQueryable через все слои, добавляя к нему дополнительные критерии, но он не получает выполнение/оценку, пока вы на самом деле его не нажмете. Это также означает, что вам не нужно выбирать и извлекать тонны данных, которые вы в конечном итоге отбрасываете.

Вы не можете сделать это с классическим статическим списком - вам нужно выбрать данные, возможно, отбросить их много позже в процессе - в конце концов, у вас есть статический список.

+2

+1 Очень описательный ответ marc ... –

7

IQueryable позволяет вам делать запросы с использованием LINQ, так же как запросы LINQ to Object, где запросы фактически «скомпилированы» и выполняются в другом месте.

Наиболее распространенные реализации работают с базами данных. Если вы используете List<T> и LINQ to Objects, вы загружаете всю «таблицу» данных в память, а затем выполняете свой запрос против нее.

С помощью IQueryable<T> ссылка LINQ может «перевести» вашу инструкцию LINQ в настоящий код SQL и запустить ее в базе данных. Результаты могут быть возвращены вам и перечислены.

Это намного эффективнее, особенно если вы работаете в системах N-Tiered.

4

Запросы LINQ от IEnumerable<T> производят делегаты (методы), которые при вызове выполняют описанный запрос.

Запросы LINQ от IQueryable<T> производят expression trees, структуру данных, которая представляет код, создавший запрос. Поставщики LINQ, такие как LINQ to SQL, интерпретируют эти структуры данных, генерируя один и тот же запрос на целевой платформе (в этом случае T-SQL).

Для примера того, как компилятор интерпретирует синтаксис запросов против IQueryable<T> см моего ответа на этот вопрос:

Building Dynamic LINQ Queries based on Combobox Value