【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

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

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

【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

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

【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

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

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

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

情况一:

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

追踪SQL:

【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

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

情况二:

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

追踪SQL:

【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

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

【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

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

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

【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

此时执行的SQL是:

【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

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

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

【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

此时执行的SQL是:

【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

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

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

【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

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

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

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

下面是MSDN给出的例子:

List<int> grades = new List<int> { , , , ,  };

// 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);

执行结果:

【EF学习笔记12】----------解释查询和本地查询 区分 Enumerable 和 Queryable

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

上一篇:Linux学习笔记2——Linux中常用文件目录操作命令


下一篇:Python中Opencv和PIL.Image读取图片的差异对比