我试图理解IQueryable,ICollection,IList& IDictionary接口 这对于迭代,索引,查询等基本操作来说更快。
像Collection,List,Dictionary等类这样的类可以很好地启动这些接口,什么时候应该使用这些类。使用这些类比其他类的基本优势。
我尝试阅读其他类似问题的帖子,但没有回答我的完整问题。 谢谢你的帮助。
答案 0 :(得分:102)
所有这些接口都继承自 IEnumerable ,您应该确保理解。该接口基本上允许您在foreach
语句中使用该类(在C#中)。
每个MSDN文档都很不错,所以我会从那里开始理解你的理解。
答案 1 :(得分:3)
IQueryable,IList,IDictionary,ICollection继承IEnumerable接口。 类型集合的所有接口都将继承IEnumerable接口。
IEnumerable和IQueryable之间的差异 IEnumerable : - 运行返回IEnumerable类型的查询时。 IEnumerable将首先执行第一个查询,然后执行为该查询编写的子查询。
示例: - 如果您想从特定国家/地区获取前10个人口记录,那么我们将在LinQ中使用的查询
IEnumerable _Population =来自印度的s选择s.population; // First Query _Population = _Population.take(10); //第二次查询
现在,如果我们执行此查询,首先将执行First Query,IEnumerable将从sql server获取所有填充的记录,然后它将数据存储在In Process内存中,然后执行前10个填充next Query。(在sql server上执行两次)。
如果我们使用IQueryable执行相同的查询。
IQueryable _Population =来自印度的s选择s.population; // First Query _Population = _Population.take(10); //第二次查询
在这个IQueryable中,它将同时执行两个查询,因为它将获得单个查询中前10名的填充,而不是获取数据并再次过滤前10个。(一次执行sql server)。
IQueryable和IEnumerable的结论
答案 2 :(得分:3)
我注意到上面@ gunny229的答案中有几个问题,这就是我写这篇文章的原因。我也在他的帖子的评论区域中提到了这些问题。为了纠正这个帖子,我不得不重写几乎所有帖子,所以我想创建自己的帖子。我并不打算完整地讨论OP的问题,但是我想指出使用LINQ to SQL 时IQueryable和IEnumerable之间的差异。
我在DB(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
表中获取前2条记录。所以,我在我的控制台应用程序中添加了一个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 Server实例上启动了一个SQL Query profiler会话,这是执行摘要:
SELECT TOP (2) [c].[Salary] AS [Salary] FROM [dbo].[Employee] AS [c]
只是IQueryable
足够聪明,可以在数据库服务器端本身应用Top (2)
子句,因此它只能通过网络传输5条记录中的2条。客户端计算机端根本不需要任何进一步的内存中过滤。
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);
}
}
在这种情况下执行摘要:
SELECT [Extent1].[Salary] AS [Salary]
FROM [dbo].[Employee] AS [Extent1]
现在问题IEnumerable
带来了Salary
表中存在的所有5条记录,然后在客户端计算机上执行了内存过滤以获得前2条记录。因此,更多的数据(在这种情况下为3个额外的记录)不必要地通过线路传输。