IQueryable和IEnumerable之间差异的真实例子?

时间:2017-04-17 11:22:18

标签: c# linq ienumerable iqueryable

我知道IQueryable的优点是在服务器上运行过滤器,而不是加载内存中的所有记录,如IEnumerable,但是在代码中看起来如何,例如,如果我有这个代码:

var data = context.Books.Where(x => x.Id > 930);

如果我有1000条记录,那么它只会加载70条记录,并迭代它们,我将data转换为List:

var list = data.ToList(); //has only 70 records

IEnumerable首先必须通过IQueryable加载所有记录的情况如何? 即获得上述示例的IEnumerable版本:

var eData = context.Books.Where(x => x.Id > 930).ToList();

Aren他们一样吗?最后一个代码只是组合上面两行代码?

3 个答案:

答案 0 :(得分:6)

代码中没有IEnumerable示例。两个

var data = context.Books.Where(x => x.Id >930); // Queryable.Where(Expression)

var eData = context.Books.Where(x => x.Id >930).ToList(); // Queryable.Where(Expression)

使用IQueryable扩展将表达式转换为SQL查询并在服务器端运行它。 dataeData之间的唯一区别是您在第二种情况下立即处理查询结果(即枚举它们并放入列表中)。如果您想使用IEnumerable

var eData = context.Books.AsEnumerable().Where(x => x.Id >930); // Enumerable.Where(Lambda)

这里的不同之处在于您可以使用过滤谓词中的任何代码来过滤集合。因为此谓词不会转换为SQL以在服务器端运行。例如。您可以运行自定义方法:

var eData = context.Books.AsEnumerable().Where(x => _someObject.CheckBook(x));

但所有图书都应该从服务器下载到客户端,以便运行IEnumerable查询。

答案 1 :(得分:2)

以下代码行不会获取内存中的记录,直到您对其进行迭代或使用ToList()实现它:

var data = context.Books.Where(x => x.Id > 930); // this does not immediately executes query

当你在这种情况下放置ToList()时,只会在服务器上执行查询,结果将被带入内存,这是你的第一个和最后一个代码示例的主要区别。

唯一要记住的是使IEnumerable导致查询被执行,所有结果都将被加载到内存中。

答案 2 :(得分:1)

IEnumerable最适合In-Memory集合,这意味着数据已经在你的列表中,你可以查询。

IQueryable最适合使用OData查询的Api调用。它将准备Sql或命令。当我们尝试使用查询结果时,它只会命中数据库来获取数据。