表达式目录树
什么是表达式目录树呢?用于表示Lambda表达式逻辑的一种数据结构,表达式树也可以称作表达式目录树,它 将代码表示成一个对象树,而不是可执行的代码。这个跟汇编原理一样,我们找到关键字,把这些语句翻译成机器码,我们这里的关键字就是表达式树里面的节点,然后分析语法词法,最后变成机器可识别的指令。
表达式目录树有什么作用呢?我们在使用ef框架的时候经常使用linq,使用linq to sql 的时候有多种方式,直接写from xx select,也可以使用lambda表达式,都是把这种语法翻译成可执行的sql,这里我们就会把lambda表达式转换成表达式树,对这个语句进行翻译,然后再在数据库中执行SQL语句,把返回的结果再返回给一个 IQueryable集合
怎么使用呢?lambda 表达式被分配给Expressions类型的变量,则编译器可以执行代码以创建表示该 lambda 表达式的表达式树。
下面我们来看例子
using System.Linq.Expressions; static void Main(string[] args) { Expression<Func<int, int, int>> expression = (a, b) => a + b; var parmeter1 = expression.Parameters[0]; var parmeter2 = expression.Parameters[1]; BinaryExpression body = (BinaryExpression)expression.Body; ParameterExpression left = (ParameterExpression)body.Left; ParameterExpression right = (ParameterExpression)body.Right; var symbols = body.NodeType; int result = expression.Compile()(2, 3); Console.WriteLine("表达式:{0}", parmeter1); Console.WriteLine("表达式体:{0}", body); Console.WriteLine("表达式左边节点:{0}", left); Console.WriteLine("表达式右边节点:{0}", right); Console.WriteLine("表达式符号:{0}", symbols); Console.WriteLine("表达式执行结果:{0}", result); Console.Read(); }
执行结果如下:
表达式:a 表达式体:(a + b) 表达式左边节点:a 表达式右边节点:b 表达式符号:Add 表达式执行结果:5
创建表达式目录树
这里我们用表达式创建表达式:(a, b) => (a + b)
int a = 100; int b = 200; ParameterExpression left = Expression.Parameter(typeof(int), "a"); ParameterExpression right = Expression.Parameter(typeof(int), "a"); BinaryExpression binary = Expression.Add(left, right); Expression<Func<int, int, int>> expression = Expression.Lambda<Func<int, int, int>>(binary, left, right); Console.WriteLine($"{expression.ToString()}");//结果:(a, b) => (a + b) Console.WriteLine(expression.Compile().Invoke(a, b));//调用
下面我们再来一个,x=>x.ID.ToString().Equals("3")
我们先来分析下这里的步骤,首先是x找到ID字段,然后执行ToString()方法,最后执行Equals("3")
我们来看代码
public class Student { public int ID { get; set; } public string Name { get; set; } public int Age { get; set; } }
//定义x ParameterExpression parameterExpression = Expression.Parameter(typeof(Student), "x"); //定义匹配常量 var constant = Expression.Constant("3"); var filedId = typeof(Student).GetProperty("ID"); //x.ID var filedExp = Expression.Property(parameterExpression, filedId); //调用ToString() var toString = typeof(int).GetMethod("ToString", new Type[] { }); //x.ID.ToString() var toStringExp = Expression.Call(filedExp, toString, new Expression[0]); //调用Equals() var equals = typeof(string).GetMethod("Equals", new Type[] { typeof(string) }); //x.ID.ToString().Equals("3") var equalsExp = Expression.Call(toStringExp, equals, new Expression[] { constant }); //表达式目录树转lambda表达式 x=>x.ID.ToString().Equals("3") Expression<Func<Student, bool>> expression = Expression.Lambda<Func<Student, bool>>(equalsExp, new ParameterExpression[] { parameterExpression }); //执行 true bool result = expression.Compile()(new Student() { ID =3, Name ="张三", Age =20 });
发表评论 取消回复