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 查询并在服务器端运行。 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查询,所有书籍都应该从服务器下载到客户端。

【讨论】:

这是否与将变量定义为IQueryableIEnumerable一样: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 有啥区别 [重复]

IEnumerable 和 IQueryable

IQueryable 和 IEnumerable 之间差异的真实示例? [复制]

IQueryable和IEnumerable,IList的区别

C# IQueryable和IEnumerable的区别

我的 Entity Framework 存储库和服务层方法应返回哪些类型:List、IEnumerable、IQueryable?