Какая разница между IQueryable и IEnumerable

Я смущен относительно разницы. Я новичок в .Net, я знаю, что могу запросить IEnumerables с помощью расширений Linq. Итак, что это за IQueryable и как оно отличается?


См. также В чем разница между IQueryable [T] и IEnumerable [T]?, которые перекрываются с этим вопросом.

Ответ 1

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

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

Например:

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<Person, bool>), который может быть выполнен как любой другой метод. Enumerable.Where выполнит метод один раз для каждого человека, yield значения, для которых возвращаемый метод true.

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

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

См:

Ответ 2

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

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

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

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

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

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

Ответ 3

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

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

Ответ 4

IEnumerable

IEnumerable<Employee> emp = ent.Employees;
IEnumerable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();

IEnumerable

IQueryable

IQueryable<Employee> emp = ent.Employees;
IEnumerable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();

IQueryable

Итак, основное отличие между "IQueryable" и "IEnumerable" заключается в том, где выполняется логика фильтра. Один выполняется на стороне клиента, а другой выполняется в базе данных.

Также обратите внимание, что интерфейс "IQueryable" наследуется от "IEnumerable" , поэтому любое "IEnumerable" может выполнять "IQueryable" .

Ответ 5

IEnumerable IEnumerable лучше всего подходит для работы с коллекцией памяти. IEnumerable не перемещается между элементами, это только передовая коллекция.

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

Поэтому, когда вам нужно просто перебирать коллекцию в памяти, используйте IEnumerable, если вам нужно делать какие-либо манипуляции с коллекцией, например, с помощью набора данных и других источников данных, используйте IQueryable

Ответ 6

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

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

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

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

Ответ 7

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

Ответ 8

Во-первых, IEnumerable находятся в пространстве имен System.Collections, тогда как IQueryable находятся в пространстве имен System.Linq. Если вы используете IEnumerable при запросе данных из коллекций в памяти, таких как List, Array collection и т.д. И при запросе данных из коллекций из памяти (например, удаленной базы данных, службы), поэтому вы используете IQueryable. Поскольку при запросе данных из базы данных IEnumerable выполняет запрос выбора на стороне сервера, загружает данные в памяти на стороне клиента и затем фильтрует данные. Следовательно, больше работает и становится медленным. При запросе данных из базы данных IQueryable выполняет запрос выбора на стороне сервера со всеми фильтрами. Следовательно, делает меньше работы и становится быстрым.