表达式树的作用
最常用到的无非就是ORM的删查改的条件,ORM就是在ado.Net的基础上封装了一层表达式,最后还是将表达式解析成sql,由ado.Net去执行。
那么我们能将表达式树解析成字符串,那么也能反过来。例如运费系统,在后台设置定义好一套计算规则。例如:对应不同的发货渠道,什么重量取哪个区间的费用,多于哪个阶段的费用还要额外费用。我们可以通过解析这套计算规则拼装好表达式树传入参数进行计算。。。
还有别的在评论补充下。。。
不扯多,现在我们只拿解析表达式树来学习。
创建表达式
Expression<Func<Users, bool>> expressionUser = users => users.Name == "SkyChen"
从上图可以看见有很多属性,在表达式主体(属性Body),我们暂时只关注三个属性,Left(左节点)、Right(右节点)和 NodeType (当前节点类型)
简单解析
表达式主体(users.Name == "SkyChen")是一个二元运算表达式,因此可以将Body转换成 BinaryExpression 类型来访问Left和Right。
Left 和 Right 的 NodeType 分别为 MemberAccess(从字段或属性进行读取的运算)、Constant(常量)。
因此可以将 Left 转换成 MemberExpression 类型来访问 Member 属性,将 Right 转换成 ConstantExpression 类型来访问 Value 属性。具体代码如下:
public static string ResolveExpression(Expression<Func<Users, bool>> expression) { var bodyNode = (BinaryExpression)expression.Body; var leftNode = (MemberExpression)bodyNode.Left; var rightNode = (ConstantExpression)bodyNode.Right; return string.Format(" {0} {2} {1} ", leftNode.Member.Name, rightNode.Value, bodyNode.NodeType.TransferExpressionType()); }
TransferExpressionType 是针对部分 ExpressionType 的一个转换。
public static string TransferExpressionType(this ExpressionType expressionType) { string type = ""; switch (expressionType) { case ExpressionType.Equal: type = "="; break; case ExpressionType.GreaterThanOrEqual: type = ">="; break; case ExpressionType.LessThanOrEqual: type = "<="; break; case ExpressionType.NotEqual: type = "!="; break; case ExpressionType.AndAlso: type = "And"; break; case ExpressionType.OrElse: type = "Or"; break; } return type; }
那么。一个最简单的表达式解析成where语句就完成了。
原文地址:
https://www.cnblogs.com/skychen1218/p/5730316.html
欢迎加群讨论技术,群:677373950(满了,可以加,但通过不了),2群:656732739