解释查询和本地查询 区分 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方法。

原文地址:https://www.cnblogs.com/wfy680/p/11969474.html