В чем разница между IQueryable и IEnumerable

У меня была та же проблема.

Это была моя ошибка

установка ошибки, проверяющая местоположения: CAfile: D: / git_repo / mingw32 / ssl / certs / ca-bundle .crt CApath: none

Он отлично работает для меня

Я переименую имя каталога установки git в git_repo ".

145
задан Community 23 May 2017 в 12:26
поделиться

5 ответов

IEnumerable представляет собой курсор только вперед T . В .NET 3.5 добавлены методы расширения, которые включают стандартные операторы запросов LINQ , например Where и First , с любыми операторами, требующими предикатов или анонимных функций, принимающих Func .

IQueryable реализует те же стандартные операторы запросов LINQ, но принимает Expression > для предикатов и анонимных функций. Выражение - это скомпилированное дерево выражений, разобранная версия метода («наполовину скомпилированная», если хотите), которая может быть проанализирована поставщиком запрашиваемого и использована соответствующим образом.

Например:

IEnumerable<Person> people = GetEnumerablePeople();
Person person = people.Where(x => x.Age > 18).FirstOrDefault();

IQueryable<Person> people = GetQueryablePeople();
Person person = people.Where(x => x.Age > 18).FirstOrDefault();

В первом блоке x => x.Age> 18 является анонимным методом ( Func ), который может быть выполняется как любой другой метод. Enumerable.Если будет выполнять метод один раз для каждого человека, выдаст значений, для которых метод вернул true .

Во втором блоке x => x.Age> 18 представляет собой дерево выражений ( Expression > ), которое можно рассматривать как "- свойство" Возраст "> 18".

Это позволяет существовать таким вещам, как LINQ-to-SQL, поскольку они могут анализировать дерево выражений и преобразовывать его в эквивалентный SQL.И поскольку провайдеру не нужно выполнять до тех пор, пока не будет перечислен IQueryable (в конце концов, он реализует IEnumerable ), он может комбинировать несколько операторов запроса (в приведенном выше примере Где и FirstOrDefault ), чтобы сделать более разумный выбор того, как выполнить весь запрос в отношении базового источника данных (например, использование SELECT TOP 1 в SQL).

См .:

185
ответ дан 23 November 2019 в 22:29
поделиться

Принципиальная разница в том, что IEnumerable будет постоянно перечислять все свои элементы, в то время как IQueryable будет перечислять элементы или даже выполнять другие действия на основе запроса. Запрос - это выражение (представление данных кода .Net), которое IQueryProvider должен исследовать / интерпретировать / компилировать / что угодно, чтобы получить результаты.

Наличие выражения запроса дает два преимущества.

Первое преимущество - оптимизация. Поскольку в выражение запроса включены такие модификаторы, как «Где», IQueryProvider может применять невозможные в противном случае оптимизации. Вместо того, чтобы возвращать все элементы, а затем отбрасывать большинство из них из-за предложения Where, поставщик может использовать хеш-таблицу для поиска элементов с заданным ключом.

Второе преимущество - гибкость. Поскольку выражения являются доступными для изучения структурами данных, вы можете делать такие вещи, как сериализовать запрос и отправлять его на удаленный компьютер (например, linq-to-sql).

9
ответ дан 23 November 2019 в 22:29
поделиться

В реальной жизни, если вы используете ORM, например LINQ-to-SQL

  • Если вы создаете IQueryable , то запрос можно преобразовать в sql и запустить на сервере базы данных
  • . Если вы создадите IEnumerable , то все строки будут загружены в память как объекты перед выполнением запроса.

В обоих случаях, если вы не вызываете ToList () или ToArray () , то запрос будет выполняться каждый раз, когда он используется, так что, скажем, у вас есть IQueryable и вы заполняете из него 4 списка, тогда запрос будет выполнен для базы данных 4 раза.

Также, если вы расширите свой запрос:

q.Select(x.name = "a").ToList()

Тогда с IQueryable сгенерированный SQL будет содержать , где name = "a" , но с IEnumerable многие другие роли будут извлечены из базы данных, тогда проверка x.name = "a" будет выполнена .NET.

80
ответ дан 23 November 2019 в 22:29
поделиться

«Основное различие заключается в что методы расширения, определенные для IQueryable, принимают объекты Expression вместо объектов Func, что означает, что делегат, который он получает, является деревом выражений, а не вызываемым методом. IEnumerable отлично подходит для работы с коллекциями в памяти, но IQueryable позволяет использовать удаленный источник данных , например, база данных или веб-сервис »

Источник: здесь

36
ответ дан 23 November 2019 в 22:29
поделиться

IQueriable - это то же самое, что и IEnumerable, но он также предоставляет дополнительные функции для реализации пользовательских запросов с помощью Linq. Вот описание на MSDN: http://msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx

1
ответ дан 23 November 2019 в 22:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: