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

    C#中IQueryable和IEnumerable的区别

    为什么EF查询后返回的是IQueryable<T>而不是IEnumerable<T>

    当我们IQueryable<T>.Where(x=>x.xxx=="123")时。其实Where方法内部应该是调用了IQueryable接口中的IQueryProvider属性的CreateQuery(Expresstion expresstion)方法,
    然后将方法的返回值又返回出来。
    而参数(Expresstion )呢?则是IQueryable
    <T>.Where(x=>x.xxx=="123")2部分的Expresstion相并。所以IQueryable只是创建条件。 那什么时候执行呢?因为我们的IQueryable<T>继承了IEnumabler<T>,所以我们必须实现GetEnumerator()
    我们ToList或foreach时,其实就会调用GetEnumerator()。这时我们就调用Execute进行解析Expresstion,从而得到我们想要的结果。 总结就是IQueryable只是创建条件,当我们调用a.Where(x
    =>xxx)时,其实是将a与后面的条件相并,生成一个新的IQueryable。
    当我们foreach时就会调用GetEnumerator()。
    这时我们一般会调用IQueryProvider里的Execute去解析Expresstion并查询出我们想要的结果

    1. 要明白一点,IQueryable接口是继承自IEnumerable的接口的.

    2. IQueryable中有表达式树, 这可以看作是它的一个优势。所以,使用IQueryable操作时,比如对数据的过滤,排序等操作, 这些都会先缓存到表达式树中. 当对数据库操作真正发生时,它才会将表达式树执行来获取数据。

    这也就是说,比如选择top 2两行数据, 它会先在表达式树中缓存这个过滤取top 2的操作。待到操作数据库时,它就会在数据库中筛选top 2数据。

    =》 IQueryable 有延时加载机制, 它直接从数据库中筛选数据.

    3. IEnumerable, 它对数据进行操作时,和IQueryable不同,它会事先把所有的数据从数据库获取,放到内存中。然后,在内存中对这些数据进行筛选操作,包括过滤,排序等.  => IEnumerable 在内存中对数据进行筛选

     在Controller中调用

    public class HomeController : Controller
    {
         private readonly IEmployeeRepository _employeeRepository;
         public HomeController(IEmployeeRepository employeeRepository)
         {
               _employeeRepository = employeeRepository;
         }
    
         public ActionResult Index()
         {
              //用IEnumerable返回结果测试
              var employees = _employeeRepository.GetIEnumerableEmployees().Take(2);
    
             //用IQueryable返回结果测试
           //  var employees = _employeeRepository.GetIQueryableEmployees().Take(2);
    
          return View(employees);
         }
    
    }

     使用MiniProfiler来检测,会发现两者的区别

    使用IEnumerable检测发现,它在数据库中执行的语句是:

    SELECT
    [Extent].[Id] AS [Id],
    [Extent].[Name] AS [Name],
    [Extent].[Department] AS [Department]
    FROM [dbo].[Employee] AS [Extent]
    可见,它从数据库中取出了所有数据。然后在内存中再筛选.

    使用IQueryable检测发现,它在数据库中执行的语句是:

    SELECT TOP (2)
    [Extent].[Id] AS [Id],
    [Extent].[Name] AS [Name],
    [Extent].[Department] AS [Department]
    FROM [dbo].[Employee] AS [Extent]
    可见,它只从数据库中取出了两条数据

     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    IQueryable接口与IEnumberable接口的区别:

    IEnumerable<T> 泛型类在调用自己的SKip 和 Take 等扩展方法之前数据就已经加载在本地内存里了,

    而IQueryable<T> 是将Skip ,take 这些方法表达式翻译成T-SQL语句之后再向SQL服务器发送命令,它并不是把所有数据都加载到内存里来才进行条件过滤。

  • 相关阅读:
    JS模板引擎 :ArtTemplate (2)
    JS模板引擎 :ArtTemplate (1)
    nodeJs 初探 ~
    javascript高级函数
    Js高程笔记->引用类型
    html5离线存储
    (摘抄)HTTP 协议详解
    cordova /phonegap 自定义插件
    phonegap/cordova常用命令
    phonegap上传以及下载图片
  • 原文地址:https://www.cnblogs.com/ZkbFighting/p/13285680.html
Copyright © 2011-2022 走看看