认识IQueryable和IQueryProvider接口
1.Func<Student, bool>和Expression<Func<Student, bool>>的区别
class Program
{
static void Main(string[] args)
{
Func<Student, bool> func = t => t.Name == "";
//匿名函数
Expression<Func<Student, bool>> expression = t => t.Name == "";
//表达式树 有Body Right、Left,Right里面又有Right、Left,它们的类型都是继承自 Expression 。这种节点下面有节点,可以无限附加下去的数据结构我们称为树结构数据。也就是我们的表达式树。
Console.Read();
}
} public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
public string Sex { get; set; }
}
2.解析表达式树
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions; namespace RedisTest
{
class Program
{
static void Main(string[] args)
{
Expression<Func<Student, bool>> expression = t => t.Name == "" && t.Name == "";
AnalysisExpression.VisitExpression(expression);
/*
运算符:AndAlso
运算符:Equal
字段名称:Name,类型:System.String
常量值:1111
运算符:Equal
字段名称:Name,类型:System.String
常量值:2222
*/
Console.Read();
}
} public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
public string Sex { get; set; }
} public static class AnalysisExpression
{
public static void VisitExpression(Expression expression)
{
switch (expression.NodeType)
{
case ExpressionType.Call://执行方法
MethodCallExpression method = expression as MethodCallExpression;
Console.WriteLine("方法名:" + method.Method.Name);
for (int i = ; i < method.Arguments.Count; i++)
VisitExpression(method.Arguments[i]);
break;
case ExpressionType.Lambda://lambda表达式
LambdaExpression lambda = expression as LambdaExpression;
VisitExpression(lambda.Body);
break;
case ExpressionType.Equal://相等比较
case ExpressionType.AndAlso://and条件运算
BinaryExpression binary = expression as BinaryExpression;
Console.WriteLine("运算符:" + expression.NodeType.ToString());
VisitExpression(binary.Left);
VisitExpression(binary.Right);
break;
case ExpressionType.Constant://常量值
ConstantExpression constant = expression as ConstantExpression;
Console.WriteLine("常量值:" + constant.Value.ToString());
break;
case ExpressionType.MemberAccess:
MemberExpression Member = expression as MemberExpression;
Console.WriteLine("字段名称:{0},类型:{1}", Member.Member.Name, Member.Type.ToString());
break;
default:
Console.Write("UnKnow");
break;
}
} }
}
3.认识IQueryable和IQueryProvider接口

ElementType 代表当然这个Query所对应的类型
Expression 包含了我们当然Query所执行的所有查询或者是其它的操作
IQueryProvider则是负责处理上面的Expression的实现

IQueryProvider只有两个操作,CreateQuery和Execute分别有泛型版本和非泛型版本。 CreatQuery用于构造一个IQueryable<T>的对象,这个类其实没有任何实现,只是继承了IQueryable和IEnumrable接口。主要用于计算指定表达式目录树所表示的查询,返回的结果是一个可枚举的类型。 而Execute会执行指定表达式目录树所表示的查询,返回指定的结果。
4.实现自己的IQueryable<T>、IQueryProvider
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions; namespace RedisTest
{
class Program
{
static void Main(string[] args)
{
var aa = new MyQueryable<Student>();
var bb = aa.Where(t => t.Name == "");
var cc = bb.Where(t => t.Sex == "男");
var dd = cc.AsEnumerable();
var ee = cc.ToList();
//每次在执行 Where 查询操作符的时候都会把lambda转化为express存放在MyQueryable的Expression里
//调用 AsEnumerable() 方法的时候并不会去实际取值(只是得到一个IEnumerable)[注意:在EF里面查询不要先取IEnumerable后滤筛,因为AsEnumerable()会生成查询全表的sql]
//执行 ToList() 方法时才去真正调用迭代器 GetEnumerator() 取值
//真正取值的时候,会去执行 IQueryProvider 中的 Execute 方法。(就是在调用这个方法的时候解析表达式数,然后执行取得结果)
//我们看到真正应该办实事的 Execute 我们却让他返回默认值了。
}
} public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
public string Sex { get; set; }
} public class MyQueryProvider : IQueryProvider
{
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
return new MyQueryable<TElement>(expression);
} public IQueryable CreateQuery(Expression expression)
{
throw new NotImplementedException();
} public TResult Execute<TResult>(Expression expression)
{
return default(TResult);
} public object Execute(Expression expression)
{
return new List<object>();
}
}
public class MyQueryable<T> : IQueryable<T>
{
public MyQueryable()
{
_provider = new MyQueryProvider();
_expression = Expression.Constant(this);
} public MyQueryable(Expression expression)
{
_provider = new MyQueryProvider();
_expression = expression;
}
public Type ElementType
{
get { return typeof(T); }
} private Expression _expression;
public Expression Expression
{
get { return _expression; }
} private IQueryProvider _provider;
public IQueryProvider Provider
{
get { return _provider; }
} public IEnumerator GetEnumerator()
{
return (Provider.Execute(Expression) as IEnumerable).GetEnumerator();
} IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
var result = _provider.Execute<List<T>>(_expression);
if (result == null)
yield break;
foreach (var item in result)
{
yield return item;
}
}
}
}
再一个例子
class Program
{
static void Main(string[] args)
{
var DB = new wolf_testEntities();
decimal aa = ;
ParameterExpression pExpression = Expression.Parameter(typeof(People));
var getPropertyValue = Expression.Property(pExpression, typeof(People).GetProperty("Num"));
ConstantExpression cExpression = Expression.Constant(aa);
BinaryExpression bExpression = Expression.MakeBinary(ExpressionType.GreaterThan, getPropertyValue, cExpression);
Expression<Func<People, bool>> lambda = Expression.Lambda<Func<People, bool>>(bExpression, pExpression);
//Expression Tree 的条件 x=>x.Num>0
var bbb = DB.People.Where(lambda).ToList();
Console.ReadLine();
}
}
认识IQueryable和IQueryProvider接口的更多相关文章
- IQueryable和IQueryProvider初尝
前言 相信大家对Entity Framework一定不陌生,我相信其中Linq To Sql是其最大的亮点之一,但是我们一直使用到现在却不曾明白内部是如何实现的,今天我们就简单的介绍IQueryabl ...
- IQueryable 与 IEnumberable 接口的区别
IQueryable 与 IEnumberable 接口的区别是: IEnumberable<T> 泛型类在调用自己的 SKip 和 Take 等扩展方法之前数据就已经加载在本地内存里了, ...
- .NET架构设计、框架设计系列文章总结
从事.NET开发到现在已经有七个年头了.慢慢的可能会很少写.NET文章了.不知不觉竟然走了这么多年,热爱.NET热爱c#.突然想对这一路的经历进行一个总结. 是时候开始下一阶段的旅途,希望这些文章可以 ...
- .NET系列文章——近一年文章分类整理,方便各位博友们查询学习
由于博主今后一段时间可能会很忙(准备出书:<.NET框架设计—模式.配置.工具>,外加换了新工作),所以博客会很少更新: 在最近一年左右时间里,博主各种.NET技术类型的文章都写过,根据博 ...
- NET系列文章
NET系列文章 由于博主今后一段时间可能会很忙(准备出书:<.NET框架设计—模式.配置.工具>,外加换了新工作),所以博客会很少更新: 在最近一年左右时间里,博主各种.NET技术类型的文 ...
- .NET深入解析LINQ框架2
1].开篇介绍 在开始看本篇文章之前先允许我打断一下各位的兴致.其实这篇文章本来是没有打算加“开篇介绍”这一小节的,后来想想还是有必要反馈一下读者的意见.经过前三篇文章的详细讲解,我们基本上对LINQ ...
- 再讲IQueryable<T>,揭开表达式树的神秘面纱
接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...
- 不可不知的表达式树(3)定制IQueryProvider
前面我们说到利用表达式树技术实现LINQ-to-SQL,实际上可以针对任何数据源,实现LINQ-to-Everything.这里还涉及到两个重要的接口即IQueryable和IQueryProvide ...
- 【转】再讲IQueryable<T>,揭开表达式树的神秘面纱
[转]再讲IQueryable<T>,揭开表达式树的神秘面纱 接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个 ...
随机推荐
- k64 datasheet学习笔记3---Chip Configuration之Analog
1.前言 本文主要讲述K64芯片配置,关于模拟部分的内容,主要包括:ADC, CMP, DAC, VREF 2.16bit SAR ADC 从上图可以看出ADC主要挂在外设总线0上,由于ADC的输入引 ...
- Linux下的Jenkins+Tomcat+Maven+Git+Shell环境的搭建使用(jenkins自动化部署)【转】
jenkins自动化部署 目标:jenkins上点构建(也可以自动检查代码变化自动构建)>>>项目部署完成. 一.安装jenkins 1.下载jenkins 这里我选择的是war包安 ...
- python3+selenium框架设计04-封装测试基类
在完成了日志类封装之后,那我们就要对测试基类进行实现,在其中对一些请求再次封装,在项目下新建一个framework文件夹,在文件夹下新建Base_Page.py文件,这是用来写测试基类的文件.在项目下 ...
- Git学习笔记04-管理修改
Git跟踪并管理的是修改,而非文件.新增文件,修改一行,删除一点,都算是修改. 在.git工作区新增一个文件,test.txt,输入test git ...然后git add add之后修改t ...
- python3+selenium入门01-环境搭建
作为一个测试,在最近两年应该有明显的感觉.那就是工作变的难找,要求变的高了,自动化测试,性能测试等.没有自动化测试能力,只会点点点工作难找不说,工资也不高.所以还是要学习一些技术.首先要学习一门编程语 ...
- strstr()函数的使用
strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串.如果是,则该函数返回str2在str1中首次出现的地址:否则,返回NULL. 实例: /** *Descriptio ...
- layui 常见的表单元素
第一步:引用文件 效果图(日期.文件上传在下面): <form class="layui-form" action=""> <div clas ...
- VUE 脚手架项目搭建
1. 概述 1.1 说明 vue-cli是一个官方发布vue.js项目脚手架,使用vue-cli可以快速创建vue项目.GitHub地址是:https://github.com/vuejs/vue-c ...
- 1)requests模块
一:requests 介绍 requests 是使用 Apache2 Licensed 许可证的 基于Python开发的HTTP 库,其在Python内置模块的基础上进行了高度的封装, 从而使得Pyt ...
- mysql 中实现多条数据同时更新
有时间我们需要对一张表进行批量数据的更新.首先我们想的是update 语句. 比如对一张订单表order_info 多条数据更新, update order_inifo set order_cod ...