2023-05-27
博客园 2023-05-27 07:28:03
接续[上篇之预告]
(资料图片仅供参考)
本篇来讲讲,如何根据前面设计的查询描述器构造出可执行的表达式。正如标题所示,实现手段将采用Expression Lambda技术。
先来看看主角System.Linq.Expressions.Expression长什么样,都有些什么东西,能做什么。 先看看它的类图:
System.Linq.Expressions.ConstantExpression 常量
System.Linq.Expressions.DefaultExpression 默认值
System.Linq.Expressions.IndexExpression 索引
System.Linq.Expressions.MemberExpression 成员(属性或字段)
System.Linq.Expressions.MethodCallExpression 方法调用
System.Linq.Expressions.ParameterExpression 参数
System.Linq.Expressions.UnaryExpression 一元运算
System.Linq.Expressions.BinaryExpression 二元运算
System.Linq.Expressions.LambdaExpression 委托
我们主要使用Expression这个类,它包含各种节点类型的 static工厂方法。特别是以下这些方法,对应了查询需要用到的逻辑、比较、数学,等各种运算操作。
| 逻辑运算 | |
|---|---|
| AndAlso(Expression, Expression) | 表示And逻辑运算 |
| OrElse(Expression, Expression) | 表示Or逻辑运算 |
| 比较运算 | |
| LessThan(Expression, Expression) | 表示小于:"<" |
| LessThanOrEqual(Expression, Expression) | 表示大于等于:“<=" |
| GreaterThan(Expression, Expression) | 表示大于:”>“ |
| GreaterThanOrEqual(Expression, Expression) | 表示大等于:”>=" |
| Equal(Expression, Expression) | 表示等于:”=“ |
| NotEqual(Expression, Expression) | 表示不等于:”!=" |
| IsTrue(Expression) | 测试表达式结果是否为“True" |
| IsFalse(Expression) | 测试表达式结果是否为“False" |
| Not(Expression) | 表示”Not" |
| 数学运算 | |
| Add(Expression, Expression) | 加法 |
| Subtract(Expression, Expression) | 减法 |
| Multiply(Expression, Expression) | 乘法 |
| Divide(Expression, Expression) | 除法 |
| Modulo(Expression, Expression) | 模除 |
| Power(Expression, Expression) | 幂运算 |
| 一些操作 | |
| Parameter(Type) | 包装一个类型为Type的参数 |
| Call(Expression, MethodInfo, Expression, Expression) | 包装一个方法调用 |
| Bind(MemberInfo, Expression) | 包装一个成员绑定,(属性或字段) |
| Quote(Expression) | 包装一个括号 |
| MakeUnary(ExpressionType, Expression, Type) | 包装一个一元运算 |
| MakeBinary(ExpressionType, Expression, Expression) | 包装一个二元运算 |
| TypeAs(Expression, Type) | 包装一个显式引用或装箱转换,其中如果转换失败则提供“null”。 |
| Coalesce(Expression, Expression, LambdaExpression) | 包装表示给定转换函数的聚结操作。 |
| 变量、常量、字段、属性 | |
| Default(Type) | 包装一个指定类型的默认值 |
| Constant(Object, Type) | 包装一个常量 |
| Assign(Expression, Expression) | 赋值操作 |
| Variable(Type, String) | 包装一个变量定义 |
| Property(Expression, MethodInfo) | 包装一个属性 |
| Field(Expression, FieldInfo) | 包装一个字段 |
| PropertyOrField(Expression, String) | 包装一个指定名称的字段或属性 |
| 要的就是这结果 | |
| Lambda(Expression, ParameterExpression[]) | 包装一个委托,带有一个参数表达式数组。 |
以上仅列出了一部分,它涵盖了全部可能要使用到的函数,语句,欲详细了解可以直接乘坐火箭到微软官方网站查看。
这此函数或功能是有了,如何使用呢?来看个例子:将SQL:Table1.A > 5 and Table1.B=3,转成(Table1)=>Table1.A > 5 && Table1.B==3;
在Expression的世界里一切都是Expression。因此首先要将Table1、A、5、B、 3先包装成Expression:
//实体类: public class Table { public int A; public int B; }然后包装各种Expression //将Table1包装成ParameterExpression: var p=Expression.Parameter(typeof(Table1),"Table1"); //将5、3这两个常量包装成ConstantExpression: var num5=Expression.Constant(5,typeof(int)); var num3=Expression.Constant(3,typeof(int)); //将两个属性包装成MemberExpression。 var a=Expression.PropertyOrField(p,"A") var b=Expression.PropertyOrField(p,"B") //构造Table1.A>5: var gt=Expression.GreaterThen(a,num5); //构造Table1.A=3: var eq=Expression.Equal(b,num3); 再构造两个比较式//构造Table1.A>5: var gt=Expression.GreaterThen(a,num5); //构造Table1.A=3: var eq=Expression.Equal(b,num3); 加上逻辑And将两个比较式连接起来//构造Table1.A>5 && Table1.A=3 var exp=Expression.AndAlso(gt,eq);结果就要出来了//结果就获得了: var lambda=Expression.Lambda() 来来来,测试一下康康接果:/*===============来来来,测试一下:===============*/ var f=lambda.Compile(); var x=f.DynamicInvoke(new Table(){A=6,B=3}); var y = f.DynamicInvoke(new Table() { A = 2, B = 3 }); Console.WriteLine("x:{0}\ny:{1}",x,y); Console.WriteLine("Lambda:{0}",lambda.ToString()); /*输出: 结果对吗?我也不知道,我撸得这么辛苦,先让电脑休息一下,各位看官只要Ctrl+C,Ctrl+V就可以看到了. */OK,其它各种操作,只要依葫芦画瓢便大功可成! 先爽一下!好,暂且爽到这里,欲看如何把括号弄成俄罗斯套娃,且看下回分解.随手点个赞,让我也爽爽,可好!
2023-05-27
2023-05-27
2023-05-27
2023-05-27
2023-05-27
2023-05-27
2023-05-27
2023-05-27
2023-05-26
2023-05-26
2023-05-26
2023-05-26
2023-05-26
2023-05-26
2023-05-26
2023-05-26
2023-05-26
2023-05-26
2023-05-26
2023-05-26