IQueryable 和 IEnumerable 之间差异的真实示例? [复制]
Posted
技术标签:
【中文标题】IQueryable 和 IEnumerable 之间差异的真实示例? [复制]【英文标题】:Real example of the differences between IQueryable and IEnumerable? [duplicate] 【发布时间】:2017-09-13 00:16:14 【问题描述】:我知道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();
它们不一样吗?最后的代码无非就是将上面两行代码结合起来?
【问题讨论】:
【参考方案1】:您的代码中没有 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
查询,所有书籍都应该从服务器下载到客户端。
【讨论】:
这是否与将变量定义为IQueryable
或IEnumerable
一样:IEnumerable list = context.Books.Where(x => x.Id >930);
IQueryable data = context.Books.Where(x => x.Id >930);
@MohamedAhmed 如果您使用IEnumerable<Book> list = context.Books.Where(x => x.Id >930);
,那么您将存储IQueryable<Book>
,它对IEnumerable
变量有一些查询。这意味着 - 所有 进一步 操作都将使用 IEnumerable
扩展。例如。 list.Where(x => x.Title != "")
将在客户端执行。但第一部分将在数据库端执行
所以这里的假设是错误的:haroldrv.com/2015/02/…(见最后一个例子)
@MohamedAhmed 这不是唯一的方法,但它是最常见的,因为您无需声明单独的 IEnumerabl
变量或将可查询的结果放入一些内存中的集合(如列表)中,就可以继续查询构造.
非常感谢,您的回答很有用【参考方案2】:
以下代码行不会获取内存中的记录,除非您对其进行迭代或使用 ToList()
实现它:
var data = context.Books.Where(x => x.Id > 930); // this does not immediately executes query
当您输入ToList()
在这种情况下,只有查询将在服务器上执行,结果将被带入内存,这是您的第一个和最后一个代码示例的主要区别。
唯一要记住的是,将其设为IEnumerable
将导致执行查询并将所有结果加载到内存中。
【讨论】:
【参考方案3】:IEnumerable 最适合 In-Memory 集合,这意味着数据将在您的列表中,您可以对其进行查询。
IQueryable 最适合使用 OData 查询的 Api 调用。它会准备 Sql 或命令。当我们尝试使用查询结果时,它只会命中数据库以获取数据。
【讨论】:
以上是关于IQueryable 和 IEnumerable 之间差异的真实示例? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
IQueryable 和 IEnumerable 有啥区别 [重复]
IQueryable 和 IEnumerable 之间差异的真实示例? [复制]
IQueryable和IEnumerable,IList的区别
我的 Entity Framework 存储库和服务层方法应返回哪些类型:List、IEnumerable、IQueryable?