zoukankan      html  css  js  c++  java
  • C# IQueryable和IEnumerable的区别

    C# IQueryable和IEnumerable的区别

    IEnumerable<T> 泛型类在调用自己的SKip 和 Take 等扩展方法之前数据就已经加载在本地内存里了,而IQueryable<T> 是将Skip ,take 这些方法表达式翻译成T-SQL语句之后再向SQL服务器发送命令。也是延迟在我要真正显示数据的时候才执行。

    LINQ查询一共提供了两类扩展方法,在System.Linq命名空间下,有两个静态类:Enumerable类,它针对继承了IEnumerable<T>接口的集合进行扩展;Queryable类,它针对继承了IQueryable<T>接口的集合类进行扩扎。接口IQueryable<T>也是继承了IEnumerable<T>接口的,所以,致使两个接口的方法在很大程度上时一致的。

    LINQ查询从功能上来讲实际上可分为3类:LINQ to OBJECTS、LINQ to SQL、LINQ to XML。设计两套接口的目的在于区分对待LINQ to OBJECTS、LINQ to SQL,两者对于查询的处理在内部使用的是完全不同的机制。针对LINQ to OBJECTS时,使用Enumerable中的扩展方法对本地集合进行排序和查询等操作,查询参数接受的是Func<>。Func<>叫做谓语表达式,相当于一个委托。针对LINQ to SQL时,则使用Queryable中的扩展方法,它接受的是Expression<>。Expression<>用于包装Func<>。LINQ to SQL最终会将表达式树转换成相应的SQL语句,然后在数据库中执行。

    简单的说:本地数据源用IEnumerable<T>,远程数据源用IQueryable<T>。

    1.Func<>谓词表达式,就是一个委托,委托一旦调用,就立即执行了,将执行结果保存在内存中。

    2.Expression是一个表达式,会存储拼接表达式树,直到在运行期最终执行。

    那么在EF中我们根据条件查询数据时,不应该把数据一次性加载到本地内存中,然后再本地内存中进行筛选,如果数据量大了,就崩溃了。

    我们需要将表达式组合好,然后再一起提交到数据库执行,返回查询结果。

    (每次在执行where查询操作符的时候IQueryProvider会为我们创建一个新的IQueryable<T>,调用AsEnumerable()方法的时候并不会去实际取值,只是

    得到了一个IEnumerable,所以EF在查询数据时候不要先取IEnumerable再去筛选数据。执行ToList方法时才会去真正调用迭代器GetEnumerator()
    取值。真正取值时候,会去执行IQueryProvider中的Excute方法.(解析表达式,然后执行取得结果))

    这就是IQueryable的延迟加载

  • 相关阅读:
    C#listbox使用方法
    poj 3894 System Engineer (二分图最大匹配--匈牙利算法)
    Java实现 蓝桥杯VIP 算法训练 连接字符串
    Java实现 蓝桥杯VIP 算法训练 连接字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 黑白无常
  • 原文地址:https://www.cnblogs.com/grj001/p/12224722.html
Copyright © 2011-2022 走看看