В чем дело с 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