Вопрос

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


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

Это было полезно?

Решение

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).

Видеть:

Другие советы

В реальной жизни, если вы используете 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.

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top