表达式目录树(Expression)

表达式目录树

什么是表达式目录树呢?用于表示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
});

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值