В чем дело с IQueryable?

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

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

Ответы

Ответ 1

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

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

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

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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

Создание динамических запросов LINQ на основе значения Combobox