Я видел много людей, говорящих о IQueryable
и я не вполне взял на том, о чем весь шум. Я всегда работаю с дженериком List
и найдите, что они очень богаты способом, которым можно "запросить" их и работать с ними, даже выполнить запросы LINQ против них.
Я задаюсь вопросом, существует ли серьезное основание начать рассматривать другой набор по умолчанию в моих проектах.
Интерфейс IQueryable
позволяет определять части запроса к удаленному поставщику LINQ (обычно к базе данных, но не обязательно) в несколько шагов и с отложенным исполнением.
Например. уровень вашей базы данных может определять некоторые ограничения (например, на основе разрешений, безопасности - что угодно), добавляя к вашему запросу предложение .Where (x => x .......)
. Но это еще не выполняется - например, вы не получаете 150 000 строк, соответствующих этому критерию.
Вместо этого вы передаете интерфейс IQueryable
на следующий уровень, бизнес-уровень, где вы, возможно, добавляете дополнительные требования и предложения where к вашему запросу - опять же, пока ничего не выполняется, вы » re также не выбрасывает 80 000 из 150 000 полученных вами строк - вы просто определяете дополнительные критерии запроса.
И слой пользовательского интерфейса может делать то же самое, например на основе пользовательского ввода в форме или чего-то еще.
Волшебство заключается в том, что вы пропускаете интерфейс IQueryable
через все уровни, добавляя к нему дополнительные критерии, но он не выполняется / не оценивается, пока вы его не заставите. Это также означает, что вы без необходимости выбираете и извлекаете тонны данных, которые впоследствии вы в конечном итоге отбрасываете.
Вы не можете сделать это с классическим статическим списком - вам нужно выбрать данные, возможно, отбросив большую часть их позже в процессе - в конце концов, у вас есть статический список.
IQueryable позволяет выполнять запросы с использованием LINQ, точно так же, как запросы LINQ to Object, где запросы фактически «компилируются» и выполняются в другом месте.
Наиболее распространенные реализации работают с базами данных. Если вы используете List
и LINQ to Objects, вы загружаете всю «таблицу» данных в память, а затем выполняете свой запрос к ней.
Используя IQueryable
, LINQ может «преобразовать» ваш оператор LINQ в реальный код SQL и запустить его в базе данных . Результаты могут быть возвращены вам и перечислены.
Это намного эффективнее, особенно если вы работаете в многоуровневых системах.
Запросы LINQ к IEnumerable
создают делегаты (методы), которые при вызове выполняют описанный запрос.
Запросы LINQ к IQueryable
создают деревья выражений , структуру данных, которая представляет код, создавший запрос. Поставщики LINQ, такие как LINQ to SQL, интерпретируют эти структуры данных, генерируя тот же запрос на целевой платформе (в данном случае T-SQL).
Пример того, как компилятор интерпретирует синтаксис запроса для IQueryable
, см. В моем ответе на этот вопрос:
Создание динамических запросов LINQ на основе значения Combobox