Разница между интерфейсами IQueryable, ICollection, IList и IDictionary - PullRequest
48 голосов
/ 16 декабря 2010

Я пытаюсь понять разницу между интерфейсами IQueryable, ICollection, IList и IDictionary что быстрее для основных операций, таких как итерации, индексирование, запросы и т. д.

какой класс, такой как Collection, List, Dictionary и т. Д., Будет хорошо инициировать с этими интерфейсами и когда мы должны использовать эти классы. Основные преимущества использования этих классов над другими.

Я пытался читать другие посты с похожими вопросами, но ничего не ответил на мои полные вопросы. Спасибо за помощь.

Ответы [ 3 ]

104 голосов
/ 16 декабря 2010

Все эти интерфейсы наследуются от IEnumerable , что вы должны убедиться, что понимаете. Этот интерфейс в основном позволяет использовать класс в операторе foreach (в C #).

  • ICollection - самый простой из перечисленных вами интерфейсов. Это перечислимый интерфейс, который поддерживает Count, и это все.
  • IList - это все, чем является ICollection, но он также поддерживает добавление и удаление элементов, извлечение элементов по индексу и т. Д. Это наиболее часто используемый интерфейс для «списков объектов», что является неопределенным I знаю.
  • IQueryable - это перечислимый интерфейс, поддерживающий LINQ. Вы всегда можете создать IQueryable из IList и использовать LINQ to Objects, но вы также найдете IQueryable, используемый для отложенного выполнения операторов SQL в LINQ to SQL и LINQ to Entities.
  • IDictionary - это другое животное в том смысле, что оно представляет собой сопоставление уникальных ключей со значениями. Он также перечислим в том смысле, что вы можете перечислять пары ключ / значение, но в противном случае он служит для других целей, чем другие, перечисленные вами.

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

3 голосов
/ 26 апреля 2017

Я заметил несколько вопросов в ответе @ gunny229 выше, поэтому я пишу этот пост. Я упомянул об этих проблемах в области комментариев своего поста. Чтобы исправить этот пост, мне пришлось бы переписать почти весь пост, поэтому я подумал о создании своего. Я не собираюсь полностью отвечать на вопросы OP, но хочу указать на разницу между IQueryable и IEnumerable при использовании LINQ to SQL .

Я создал следующую структуру в БД (скрипт DDL):

CREATE TABLE [dbo].[Employee]([PersonId] [int] NOT NULL PRIMARY KEY,[Salary] [int] NOT NULL)

Вот скрипт вставки записи (DML-скрипт):

INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(1, 20)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(2, 30)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(3, 40)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(4, 50)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(5, 60)
GO

Теперь моя цель состояла в том, чтобы просто получить две лучшие записи из таблицы Employee в базе данных. Итак, я добавил элемент ADO.NET Entity Data Model в консольное приложение, указывая на таблицу Employee в моей базе данных, и начал писать запросы LINQ.

Код для маршрута IQueryable :

using (var efContext = new EfTestEntities())
{
    IQueryable<int> employees = from e in efContext.Employees  select e.Salary;
    employees = employees.Take(2);

    foreach (var item in employees)
    {
        Console.WriteLine(item);
    }
}

Когда я начал запускать эту программу, я также запустил сеанс профилировщика SQL Query на своем экземпляре SQL Server, и вот сводная информация о выполнении:

  1. Общее количество выполненных запросов: 1
  2. Текст запроса: SELECT TOP (2) [c].[Salary] AS [Salary] FROM [dbo].[Employee] AS [c]

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

Код для IEnumerable route :

using (var efContext = new EfTestEntities())
{
    IEnumerable<int> employees = from e in efContext.Employees  select e.Salary;
    employees = employees.Take(2);

    foreach (var item in employees)
    {
        Console.WriteLine(item);
    }
}

Сводка выполнения в этом случае:

  1. Общее количество выполненных запросов: 1
  2. Текст запроса, захваченный в профилировщике SQL: SELECT [Extent1].[Salary] AS [Salary] FROM [dbo].[Employee] AS [Extent1]

Теперь дело в том, что IEnumerable собрал все 5 записей, представленных в таблице Salary, а затем выполнил фильтрацию в памяти на клиентском компьютере, чтобы получить первые две записи. Таким образом, больше данных (в данном случае 3 дополнительных записи) были переданы по проводам без необходимости.

3 голосов
/ 23 марта 2015

IQueryable, IList, IDictionary, ICollection наследует интерфейс IEnumerable. Все интерфейсы коллекции типов будут наследовать интерфейс IEnumerable.

Различия между IEnumerable и IQueryable IEnumerable : - при выполнении запроса, который возвращает тип IEnumerable. IEnumerable сначала выполняет первый запрос, а затем выполняет подзапросы, написанные для этого запроса.

Пример : - Если вы хотите получить 10 лучших записей о населении из определенной страны, тогда запрос, который мы будем использовать в LinQ, будет

IEnumerable _Population = от s в Индии select s.population; // Первый запрос _Population = _Population.take (10); // Второй запрос

Теперь, если мы выполним этот запрос, сначала будет выполнен первый запрос, IEnumerable получит записи всего населения с сервера sql, затем он сохранит данные в памяти In Process, а затем выполнит 10 самых популярных в следующий запрос. (Выполнение выполняется дважды на сервере sql).

если мы выполним тот же запрос с помощью IQueryable.

IQueryable _Population = от s в Индии select s.population; // Первый запрос _Population = _Population.take (10); // Второй запрос

в этом IQueryable он будет выполнять два запроса одновременно в том смысле, что получит заполнение, которое входит в топ-10 в одном запросе, вместо получения данных и повторной фильтрации первых 10 (одноразовое выполнение sql server).

Заключение для IQueryable и IEnumerable

  1. Если вы пишете запрос к данным в базе данных, то используйте IQueryable.
  2. Если вы запрашиваете данные в процессе, тогда использовать IEnumerable IEnumerable имеет методы GetEnumerator (), Current () и MoveNext ().
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...