Lambda表达式树解析(下)包含自定义的provider和查询
概述
前面章节,总结了Lambda树的构建,那么怎么解析Lambda表达式树那?Lambda表达式是一种委托构造而成,如果能够清晰的解析Lambda表达式树,那么就能够理解Lambda表达式要传递的正式意图。解析Lambda表达式树意义很大,比如我们用的EF框架、Rafy框架,里面封装了大量的Lambda查询表达式,通过解析表达式转换成SQL语句,即可以查询数据库,将数据呈现给前台用户;
Lambda表达式树解析
下面代码块是标识Express各个节点的信息,ExpressionType.Call标识表达式中含有方法调用,常用到该类型的3个参数为:Method.DeclaringType和Argument和object。ExpressionType.Quote标识表达式中含有一元表达式,常用到的参数是Operand,里面放置了Lamble具体表达式。

public string AnalysisExpression(Expression exp)
{
string TextSql = "";
switch (exp.NodeType)
{
case ExpressionType.Call:
{
MethodCallExpression mce = exp as MethodCallExpression;
Console.WriteLine("The Method Is {0}", mce.Method.Name);
Console.WriteLine("The Method TypeOf {0}", mce.Method.DeclaringType);
if (mce.Method.DeclaringType == typeof(string))
{
break;
}
if (mce.Method.DeclaringType != typeof(Queryable)){
break;
}
for (int i = 0; i < mce.Arguments.Count; i++)
{ TextSql+=AnalysisExpression(mce.Arguments[i]);
}
}
break;
case ExpressionType.Quote:
{
UnaryExpression ue = exp as UnaryExpression;
TextSql += AnalysisExpression(ue.Operand);
}
break;
case ExpressionType.Lambda:
{
LambdaExpression le = exp as LambdaExpression;
AnalysisExpression(le.Body);
TextSql+= ExpressTreeAnalysis.GetSqlByExpression(le.Body);
}
break;
case ExpressionType.AndAlso:
case ExpressionType.OrElse:
case ExpressionType.Equal:
{
BinaryExpression be = exp as BinaryExpression;
Console.WriteLine("The Method Is {0}", exp.NodeType.ToString());
TextSql += AnalysisExpression(be.Left);
TextSql += AnalysisExpression(be.Right);
}
break;
case ExpressionType.Constant:
{
ConstantExpression ce = exp as ConstantExpression;
Console.WriteLine("The Value Type Is {0}", ce.Value.ToString());
}
break;
case ExpressionType.Parameter:
{
ParameterExpression pe = exp as ParameterExpression;
Console.WriteLine("The Parameter Is {0}", pe.Name);
}
break;
default:
{
Console.Write("UnKnow");
}
break;
}
return TextSql;
}

由于自定义集合实现IQueryable和IQueryProvider来自定义查询项
实现IQuable定义的类:

public class BlogQueryable<T> : IQueryable<T>
{
BlogQueryProvider provider;
Expression expression; public BlogQueryable(BlogQueryProvider provider)
{
if (provider == null)
{
throw new ArgumentNullException("provider");
}
this.provider = provider;
this.expression = Expression.Constant(this);
} public BlogQueryable(BlogQueryProvider provider, Expression expression)
{
this.provider = provider;
this.expression = expression;
}
public Type ElementType
{
get
{
return typeof(T);
}
} public Expression Expression
{
get
{
return expression;
}
} public IQueryProvider Provider
{
get
{
return provider;
}
} public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>)this.provider.Execute(this.expression)).GetEnumerator();
} IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)this.provider.Execute(this.expression)).GetEnumerator();
} public void Where2(Expression<Func<T, bool>> func)
{
string TextSql = ExpressTreeAnalysis.GetSqlByExpression(func.Body);
}
}

实现IQueryProvider接口的类,CreateQuery解析表达式树而Execute则是执行解析后的SQL语句,查询数据,填充list集合:

public class BlogQueryProvider : IQueryProvider
{ public IQueryable CreateQuery(Expression expression)
{
Type elementType = expression.Type;
try
{
return (IQueryable)Activator.CreateInstance(typeof(BlogQueryable<>).MakeGenericType(elementType), new object[] { this, expression });
}
catch(TargetInvocationException tie)
{
throw tie.InnerException;
}
} public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{ //string TextSql= ExpressTreeAnalysis.GetSqlByExpression(((Expression)(expression as MethodCallExpression).Arguments[1]).bo);
//Console.WriteLine(TextSql);
AnalysisExpression(expression);
return new BlogQueryable<TElement>(this, expression);
} public object Execute(Expression expression)
{
return this.Execute2<object>(expression);
} public TResult Execute<TResult>(Expression expression)
{
return (TResult)this.Execute2<TResult>(expression);
} public TResult Execute2<TResult>(Expression expression)
{
return (TResult)Activator.CreateInstance(typeof(TResult));
}
}

具体下面即可使用查询

public void MyTestMethod()
{
Catagory cag = new Catagory("四大名著点评"); IList<Blog> Blogs = new List<Blog>();
Blog bok = new Blog() { Title = "红楼梦", Conent = "红楼梦书籍不错",
User = new Author() { UserName = "曹雪芹", BirefInfor = "中国清代著名作家" } };
bok.Catagories.Add(cag);
bok.Catagories.Add(new Catagory("红楼梦专栏"));
Blogs.Add(bok); Blog bok2 = new Blog() { Title = "三国演义", Conent = "三国鼎立时期的描述",
User = new Author() { UserName = "罗贯中", BirefInfor = "中国元末明初著名作家" } };
bok2.Catagories.Add(cag);
bok2.Catagories.Add(new Catagory("三国演义专栏"));
Blogs.Add(bok2); Blog bok3 = new Blog() { Title = "西游记", Conent = "西游记讲述四个徒弟和一个师傅取经事情",
User = new Author() { UserName = "吴承恩", BirefInfor = "中国明代杰出的小说家" } };
bok2.Catagories.Add(cag);
bok2.Catagories.Add(new Catagory("西游记专栏"));
Blogs.Add(bok3); Blog bok4 = new Blog() { Title = "水浒传", Conent = "描述梁山好汉劫富济贫的故事",
User = new Author() { UserName = "施耐庵", BirefInfor = "中国明代杰出的小说家" } };
bok2.Catagories.Add(cag);
bok2.Catagories.Add(new Catagory("水浒传专栏"));
Blogs.Add(bok4); BlogQueryProvider Provider = new BlogQueryProvider();
BlogQueryable<Blog> Quble = new BlogQueryable<Blog>(Provider); var t2 = Quble.Where(p => p.Title == "123" && p.Conent.Contains("水浒"));
}

后续:针对解析Lambda表达式树成SQL,本人也是刚刚入门,至于完全要解析成SQL,还需要研究......
https://www.cnblogs.com/xibei666/p/6858299.html
Lambda表达式树解析(下)包含自定义的provider和查询的更多相关文章
- Lambda表达式树解析(下)
概述 前面章节,总结了Lambda树的构建,那么怎么解析Lambda表达式树那?Lambda表达式是一种委托构造而成,如果能够清晰的解析Lambda表达式树,那么就能够理解Lambda表达式要传递的正 ...
- Lambda表达式树构建(上)
概述 Lambda是C#常用的语句,采用委托等方式,来封装真实的代码块.Lambda其实就是语法糖,是一个匿名函数,是一种高效的类似于函数式编程的表达式,Lambda简化了开发中需要编写的代码量.它可 ...
- 干货!表达式树解析"框架"(1)
最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 关于我和表达式树 其实我也没有深入了解表达式树一些内在实现的原理 ...
- 轻量级表达式树解析框架Faller
有话说 之前我写了3篇关于表达式树解析的文章 干货!表达式树解析"框架"(1) 干货!表达式树解析"框架"(2) 干货!表达式树解析"框架" ...
- 动态拼接lambda表达式树
前言 最近在优化同事写的代码(我们的框架用的是dapperLambda),其中有一个这样很普通的场景——界面上提供了一些查询条件框供用户来进行过滤数据.由于dapperLambda按条件查询时是传入表 ...
- 将简单的lambda表达式树转为对应的sqlwhere条件
1.Lambda的介绍 园中已经有很多关于lambda的介绍了.简单来讲就是vs编译器给我带来的语法糖,本质来讲还是匿名函数.在开发中,lambda给我们带来了很多的简便.关于lambda的演变过程可 ...
- 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截
程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构 .要想在之后的江湖历练中通关,数据结构必不可少. ...
- 用lambda表达式树替代反射
本节重点不讲反射机制,而是讲lambda表达式树来替代反射中常用的获取属性和方法,来达到相同的效果但却比反射高效. 每个人都知道,用反射调用一个方法或者对属性执行SetValue和GetValue操作 ...
- 干货!表达式树解析"框架"(2)
最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 为了过个好年,我还是赶快把这篇完成了吧 声明 本文内容需要有一定 ...
随机推荐
- Ubuntu 14.04 编译 Android 4.2.2 for Tiny4412
. . . . . 在学校里是用 Redhat 6.4 编译的 Android 4.2.2 很顺利,把源码包拷贝到笔记本上的 Ubuntu 14.04 上再编译遭遇了各种坑,所以便有了这篇博客记录解决 ...
- node学习笔记8——发布npm包
1.注册一个npm账号: 2.在控制台输入 npm login: 依次输入你的账号信息,可通过 npm whoami 来验证是否登录成功 3.初始化包,控制台输入 npm init: 完成之后,可以看 ...
- flush()的原理
输出流类似于一根管道,输出的时候先放到管道里,然后管道满了存到介质上(硬盘或其他地方),当我们输出完后管道里面可能还有剩余,就用flush()清空管道即全部存到介质上.Java默认的缓冲区大小一般是8 ...
- JS复制内容到剪贴板(兼容FF/Chrome/Safari所有浏览器)
现在浏览器种类也越来越多,诸如 IE.Firefox.Chrome.Safari等等,因此现在要实现一个js复制内容到剪贴板的小功能就不是一件那么容易的事了. 在FLASH 9 时代,有一个通杀所有浏 ...
- js if判断 遍历 替换图片地质
<script> $(document).ready(function() { var s = "The rain in Spain falls mainly in the pl ...
- h5 定位
<!DOCTYPE html> <html> <body> <p id="demo">点击这个按钮,获得您的坐标:</p> ...
- 101 个 MySQL 的调节和优化的提示
英文原文:101 Tips to MySQL Tuning and Optimization MySQL是一个功能强大的开源数据库.随着越来越多的数据库驱动的应用程序,人们一直在推动MySQL发展到它 ...
- 评点SAP HR功能及人力资源管理软件
评点SAP HR功能及人力资源管理软件 本文导航 第1页:my SAP 人力资源软件 第2页:my SAP HR协同功能 第3页:组织结构管理 第4页:mySAPTM HR的战略功能 第5页:集成 ...
- 三个支持正则表达式的行处理的工具: grep/sed/awk
grep: 全称Global Regular Expression Print, 是干什么的,不多说了: 用法:grep [-options] [pattern] [filename] 选项: -c: ...
- 嵌入式驱动开发之内核态spi ---module_spi_driver
http://blog.csdn.net/dearsq/article/details/51839083 http://blog.csdn.net/alleincao/article/details/ ...