您当前的位置: 首页 > 语文作业 > IQueryable 和 IEnumerable 的区别
IQueryable 和 IEnumerable 的区别
发布时间:2023-10-04 04:40
  1. IQueryable 和 IEnumerable 的区别
  2. 理解 .NET 中的 IEnumerable 和 IQueryable
  3. C# 仅无参数构造
  4. (转).NET 面试题系列[9] - IEnumerable
  5. C# 中的 IEnumerable、ICollection、IList
  6. IEnumerable
  7. IEnumerable
  8. SQL 中的函数选择(C# EF 实现)
  9. C#-IEnumerator 和 IEnumerable
  10. 通过 IQueryable 创建 List 泛型集合的异步方法

来源:https://www.nj-dt.com/2019/11/17/distinguish- Between-IQueryable-and-IEnumerable-in-CSharp/

前言

无论是Linq to object,还是Linq to sql还是Linq to Entity, IQueryable 和 IEnumerable两者都是延迟执行。它们之间唯一的区别是扩展方法的参数类型不同。 (不同的迭代/枚举方法?不同的对象?)

IQueryable 和 IEnumerable 的区别

  • IQueryable:扩展方法接受表达式

    对于linq至sqllinq到entityexpression必须能够转换为SQL,否则将报告错误。

  • IEnumerable:扩展方法接受 FuncFunc 是 C# 语法)。

    IEnumerable运行Linq to Object,这会强制将所有数据从数据库读取到内存中,因此可以使用C#语法。

    对于 Linq to sqlLinq to EntityFunc 没有限制,因为它使用 C# 语法来操作数据。这也从侧面说明:数据已经读入内存了。

    IEnumerable的扩展方法是Func,不会转换为sql。转换成sql的是内部的IQueryable。因此需要注意的是,条件最好限制在IQueryable,否则IQueryable可能会读取大量数据,增加时间消耗和内存。

AsEnumerable() 和 ToList() 的区别

  • ToList()立即执行。 sql会立即执行,并将数据取入内存。

  • AsEnumerable()延迟执行,只有在真正使用的时候才执行sql读取数据。 这里有坑,一定要往下看

IQueryable对象使用AsEnumerable()后,仍然是延迟执行,但此时的性质 对象它已经改变了

如前所述,IEnumerable的扩展方法接受Func(C#语法),当ie对象(iq变换)实际使用,将有 2 个步骤:

  1. 会将iq对象(转换前)的扩展方法翻译成sql语句,将查询到的数据加载到内存中,转成ie对象;
  2. 此时使用C#求解ie对象(变换后)的扩展方法即可得到最终结果。

示例:

iq 对象的 Skip 和 Take 方法将被翻译成 sql 并在数据库中执行以获得最终结果。

ie对象的Skip和Take方法会将将所有数据取入内存,在内存中执行Skip和Take会消耗大量资源。

使用场景

  • IQueryable在使用 EFCore 动态拼接多个 where 条件时使用 。 (延迟查询,每次实际使用数据时都会重新读取。)

  • IEnumerable:当扩展方法无法转换为sql时,可以使用AsEnumerable()转换为IEnumerable。因为IEnumerable的扩展方法使用C#语法来处理数据。 (延迟查询,每次实际使用数据时都会重新读取。)

  • ToList():当where条件确定后,您可以使用ToList()立即从数据库中检索数据并在以后重复使用该数据。

不过为了省事,我一般都是拼接条件后使用IQueryable,然后直接使用ToList()。 。 。

备注

异常:System.InvalidOperationException:无法多次枚举查询结果

异常情况

Linq to sqlEF(非EFCore)中,直接执行sql语句查询数据,然后数据集(IEnumerable ) 执行多个枚举操作将导致此异常。

经测试,多次Count()都会导致该异常。其他Sum()foreach等应该是一样的,需要验证。 。 。

我的理解是:数据集(IEnumerable)使用枚举器来处理每一项数据,并且枚举器只能走一次。 我不懂枚举器和迭代器,我需要研究它们。 。 。

注意,EFCore 不会出现此异常,请查找efcore执行sql的原因。

解决方案

    IEnumerable ieBs = iqBs.AsEnumerable(); //不查询数据库 ieBs = ieBs.Where(p => www.nj-dt.com > 5); //执行sql //只执行iq的条件 //查询数据库 //exec sp_executesql N'SELECT [t0].[ID], [t0].[OTAName], [t0].[OnlineSupplier], [t0].[PushUrl], [t0].[Note], [t0] .[EditCode]、[t0].[AddUser]、[t0].[PushDate]、[t0].[GetDate]、[t0].[EditDate]、[t0].[AddDate] //FROM [dbo].[BaseSupplier_OTAOnline] AS [t0] //WHERE [t0].[ID] < @p0',N'@p0 int',@p0=10 列表 bsList = ieBs.ToList(); //再次查询数据库 //exec sp_executesql N'SELECT [t0].[ID], [t0].[OTAName], [t0].[OnlineSupplier], [t0].[PushUrl], [t0].[Note], [t0] .[EditCode]、[t0].[AddUser]、[t0].[PushDate]、[t0].[GetDate]、[t0].[EditDate]、[t0].[AddDate] //FROM [dbo].[BaseSupplier_OTAOnline] AS [t0] //WHERE [t0].[ID] < @p0',N'@p0 int',@p0=10 foreach(ieB 中的 var 项目) { }

    NetCore

    测试环境:

    • AspNetCore 2.1
    • EFCore
     //不查询数据库
                IQueryable iqOta = ctx.BaseSupplier_OTAOnline.Where(p => www.nj-dt.com < 10);
    
                //不查询数据库
                IEnumerable ieOta = iqOta.AsEnumerable();
    
                //不查询数据库
                ieOta = ieOta.Where(p => www.nj-dt.com > 5);
    
                //执行sql
                //只执行iq的条件
                //查询数据库
    //SELECT [p].[ID], [p].[AddDate], [p].[AddUser], [p].[EditCode], [p].[EditDate], [p].[GetDate] , [p].[注意], [p].[OTAName], [p].[OnlineSupplier], [p].[PushDate], [p].[PushUrl]
    //FROM [BaseSupplier_OTAOnline] AS [p]
    //其中 [p].[ID] < 10
                列表 bsList = ieOta.ToList();
    
                //再次查询数据库
    //SELECT [p].[ID], [p].[AddDate], [p].[AddUser], [p].[EditCode], [p].[EditDate], [p].[GetDate] , [p].[注意], [p].[OTAName], [p].[OnlineSupplier], [p].[PushDate], [p].[PushUrl]
    //FROM [BaseSupplier_OTAOnline] AS [p]
    //其中 [p].[ID] < 10foreach(ieOta 中的 var 项目)
                {
    
                }
    

    参考

      LINQ 查询中的
    1. IEnumerable 和 IQueryable
    2. LINQ使用细节中.AsEnumerable()和.ToList()的区别
    3. 建议29:区分LINQ查询中的IEnumerabl和IQueryable - 卢敏基《编写高质量代码改善C#程序的157个建议》
相关阅读