Разница между интерфейсами IQueryable, ICollection, IList и IDictionary

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

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

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


person Praneeth    schedule 15.12.2010    source источник


Ответы (3)


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

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

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

person John Bledsoe    schedule 15.12.2010
comment
+1 за подробное объяснение этого интерфейса, но вам не хватает других моих вопросов - person Praneeth; 16.12.2010
comment
Что касается общих версий интерфейсов, ICollection ‹T› поддерживает Add / Remove / Clear / Contains / CopyTo согласно msdn.microsoft.com/en-us/library/92t2ye13.aspx - person Joshua Rodgers; 16.12.2010

Я заметил несколько проблем в ответе @ 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 в свое консольное приложение, указывающий на 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 маршрута:

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 таблице, а затем выполнила фильтрацию в памяти на клиентском компьютере, чтобы получить 2 первые записи. Таким образом, больше данных (в данном случае 3 дополнительных записи) было без надобности передано по сети.

person RBT    schedule 26.04.2017
comment
Спасибо, но я не думаю, что ответ @ gunny229 вводит в заблуждение. Да, он использовал слово «запрос», но это не в контексте базы данных. Это просто еще одно вычисление, чтобы получить два лучших. По крайней мере, я так понял, читая это. Ваше здоровье. - person Ε Г И І И О; 06.12.2019

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

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

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

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

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

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

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

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

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

  1. Если вы пишете запрос к данным в базе данных, используйте IQueryable.
  2. Если вы запрашиваете данные в процессе, используйте IEnumerable. IEnumerable имеет методы GetEnumerator (), Current () и MoveNext ().
person gunny 229    schedule 23.03.2015
comment
Действительно приятно знать разницу. (у) - person Wasim Bajwa; 27.03.2017
comment
метод расширения Take вместо этого определен на IEnumerable<T>. Я проверил, что только 1 запрос запускается в обоих случаях, будь то IEnumerable или IQueryable. Просто IEnumerable выполняет фильтрацию в памяти, которая передает нежелательные данные по сети. - person RBT; 26.04.2017