我知道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他们一样吗?最后一个代码只是组合上面两行代码?
答案 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查询并在服务器端运行它。 data
和eData
之间的唯一区别是您在第二种情况下立即处理查询结果(即枚举它们并放入列表中)。如果您想使用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或命令。当我们尝试使用查询结果时,它只会命中数据库来获取数据。