Разница между интерфейсами IQueryable, ICollection, IList и IDictionary
Я пытаюсь понять разницу между интерфейсами IQueryable, ICollection, IList и IDictionary, которые более быстры для базовых операций, таких как итерации, индексирование, запросы и многое другое.
какой класс, такой как Collection, List, Dictionary и т. д., было бы хорошо начать с этих интерфейсов и когда мы должны использовать эти классы. Основные преимущества использования этих классов над другими.
Я пытался читать другие посты с похожими вопросами, но ничего не ответил на мои полные вопросы. Спасибо за помощь.
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 для каждого из них является достойной, поэтому я бы начал с того, чтобы завершить ваше понимание.
Я заметил несколько проблем в ответе @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
Теперь моей целью было просто получить топ-2 записи от 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-запросов на своем экземпляре SQL Server, и вот сводная таблица выполнения:
- Общее количество выполненных запросов: 1
- Текст запроса:
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
- Текст запроса, захваченный в профилировщике SQL:
SELECT [Extent1].[Salary] AS [Salary] FROM [dbo].[Employee] AS [Extent1]
Теперь дело в том, IEnumerable
принес все 5 записей, присутствующих в Salary
таблицы, а затем выполнил фильтрацию в памяти на клиентском компьютере, чтобы получить 2 верхние записи. Таким образом, дополнительные данные (в данном случае 3 дополнительные записи) были переданы по проводам без необходимости.
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),
Заключение для IQueryable и IEnumerable
- Если вы пишете запрос к данным в базе данных, используйте IQueryable.
- Если вы запрашиваете данные, находящиеся в процессе, используйте IEnumerable. IEnumerable имеет методы GetEnumerator(),Current() и MoveNext().