zoukankan      html  css  js  c++  java
  • 【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

    简单介绍:Enumerable 和 Queryable 他们都是静态类,位于命名控件 System.Linq下,分别为IEnumerable<T>和IQueryable<T>提供方法扩展。关于扩展方法请查看:.NET扩展方法一章

    Enumerable 为 IEnumerable<T> 泛型接口提供扩展。Queryable为IQueryable<T>泛型接口提供扩展,IQueryable接口继承了IEnumerable接口,这两个接口具有几乎相同的签名,但是执行方式大不相同。

       

    先来看一下我们的表结构:

    现在,我们查询分数大于80分的学生:分析下面两句代码

    IEnumerable<Student> query1 = db.Student.Where(s => s.Score >= 80);
    IEnumerable<Student> query2 = db.Student.AsEnumerable().Where(s => s.Score >= 80);

    虽然返回类型都是 IEnumerable<T>,他们的执行原理有什么不同?

    情况一:

    using (var db = new Entities())
    {
        IQueryable<Student> query1 = db.Student.Where(s => s.Score >= 80);
    
        foreach (var st in query1)
        {
            Console.WriteLine(st.StudentName + st.Score);
        }
    }

    追踪SQL:

    说明:上面的实例实际上是调用Queryable中定义的扩展方法,将查询条件解析为查询表达式数,最终转换成sql语句执行。

    情况二:

    using (var db = new Entities())
    {
        IEnumerable<Student> query1 = db.Student.AsEnumerable().Where(s => s.Score >= 80);
    
        foreach (var st in query1)
        {
            Console.WriteLine(st.StudentName + st.Score);
        }
    }

    追踪SQL:

    说明:我们调用了AsEnumerable方法,下面是MSDN的解释:

     通俗点讲,就是:AsEnumerable方法为我们提供了一种选择,选择分2种:

    1.不调用AsEnumerable方法时:将查询条件解析为表达式树,实际调用 Queryable类中的Where方法

    此时执行的SQL是:

    程序将查询条件转化为了最终的SQL语句,发送到远程数据库查询。

    2.调用AsEnumerable方法时: 将查询条件视为一个委托,实际调用 Enumerable类中的Where方法

    此时执行的SQL是:

    程序实际上是先将 所有学生数据全部取出,在内存中进行过滤。

    这两种方式都是延迟执行,遍历元素的时候才会真正的去查询数据库,执行结果如下:

    注意:AsEnumerable方法要在查询方法之前调用,如下的方式执行的结果与不调用AsEnumerable没差别,仍然执行Queryable中的方法。

    IEnumerable<Student> query1 = db.Student.Where(s => s.Score >= 80).AsEnumerable();

    补充:另一个方法AsQueryable定义在Queryable静态类中,是将实现了IEnumerable<T>接口的对象转化为 IQueryable<T>对象,

    下面是MSDN给出的例子:

    List<int> grades = new List<int> { 78, 92, 100, 37, 81 };
    
    // Convert the List to an IQueryable<int>.
    IQueryable<int> iqueryable = grades.AsQueryable();
    
    // Get the Expression property of the IQueryable object.
    System.Linq.Expressions.Expression expressionTree =
        iqueryable.Expression;
    
    Console.WriteLine("The NodeType of the expression tree is: "
        + expressionTree.NodeType.ToString());
    Console.WriteLine("The Type of the expression tree is: "
        + expressionTree.Type.Name);

    执行结果:

    到数据源你不清楚是IEnumerable还是IQueryable时,调用AsQueryable方法。

  • 相关阅读:
    UVA 818 Cutting Chains 切断圆环链 (暴力dfs)
    UVA 211 The Domino Effect 多米诺效应 (回溯)
    UVA225 Golygons 黄金图形(dfs+回溯)
    UVA208 Firetruck 消防车(并查集,dfs)
    UVA11212 EditingaBook ( IDA*搜索)
    UVA 140 Brandwidth 带宽 (dfs回溯)
    uva 1601 poj 3523 Morning after holloween 万圣节后的早晨 (经典搜索,双向bfs+预处理优化+状态压缩位运算)
    UVA10410 TreeReconstruction 树重建 (dfs,bfs序的一些性质,以及用栈处理递归 )
    cdoj 414 八数码 (双向bfs+康拓展开,A*)
    UVA 246 10-20-30 10-20-30游戏 模拟+STL双端队列deque
  • 原文地址:https://www.cnblogs.com/gosky/p/5757575.html
Copyright © 2011-2022 走看看