表达式树的解析(一)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 表达式树的解析(一)

前言


公司的orm框架在dapper的基础上扩展了一套表达式的方法,当时就研究了一下,把学习过程和结果记录下来,和大家分享。


有人会说重复造轮子没必要,直接上EF。


从我的角度来看重复造轮子的原因有以下两种:

1、研究造轮子的原理

2、轮子不满足现在的开发需要



表达式树的作用


最常用到的无非就是ORM的删查改的条件,ORM就是在ado.Net的基础上封装了一层表达式,最后还是将表达式解析成sql,由ado.Net去执行。


那么我们能将表达式树解析成字符串,那么也能反过来。例如运费系统,在后台设置定义好一套计算规则。例如:对应不同的发货渠道,什么重量取哪个区间的费用,多于哪个阶段的费用还要额外费用。我们可以通过解析这套计算规则拼装好表达式树传入参数进行计算。。。还有别的在评论补充下。。。不扯多,现在我们只拿解析表达式树来学习。


创建表达式


首先创建4个属性的Users类

 

 1 namespace CG.ExpressionProject
 2 {
 3     /// <summary>
 4     /// 用户类
 5     /// </summary>
 6     public class Users
 7     {
 8         public string Name { get; set; }
 9 
10         public int Phone { get; set; }
11 
12         public int Sex { get; set; }
13 
14         public int Age { get; set; }
15     }
16 }


接着,我们从最简单的开始,写一个二元运算表达式,F5调试监控观察。

Expression<Func<Users, bool>> expressionUser = users => users.Name == "SkyChen"


image.png


从上图可以看见有很多属性,在表达式主体(属性Body),我们暂时只关注三个属性,Left(左节点)、Right(右节点)和 NodeType (当前节点类型)


image.png


简单解析


表达式主体(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语句就完成了。


image.png


目录
相关文章
|
12天前
|
Java API
Java 8新特性:Lambda表达式与Stream API的深度解析
【7月更文挑战第61天】本文将深入探讨Java 8中的两个重要特性:Lambda表达式和Stream API。我们将首先介绍Lambda表达式的基本概念和语法,然后详细解析Stream API的使用和优势。最后,我们将通过实例代码演示如何结合使用Lambda表达式和Stream API,以提高Java编程的效率和可读性。
|
18天前
|
JSON 数据格式 索引
【Azure Developer】Azure Logic App 示例: 解析 Request Body 的 JSON 的表达式? triggerBody()?
【Azure Developer】Azure Logic App 示例: 解析 Request Body 的 JSON 的表达式? triggerBody()?
|
2月前
|
SQL 开发框架 前端开发
在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式
在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式
|
3月前
|
前端开发 安全 Java
Spring EL表达式:概念、特性与应用深入解析
Spring EL表达式:概念、特性与应用深入解析
|
3月前
深入解析AVL树:高效实现二叉平衡搜索树(2)
深入解析AVL树:高效实现二叉平衡搜索树
14 1
|
3月前
|
存储
深入解析AVL树:高效实现二叉平衡搜索树
深入解析AVL树:高效实现二叉平衡搜索树
14 1
|
3月前
|
存储 安全 Java
深入解析Java HashMap的高性能扩容机制与树化优化
深入解析Java HashMap的高性能扩容机制与树化优化
97 1
|
3月前
|
传感器 存储 SQL
ClickHouse(15)ClickHouse合并树MergeTree家族表引擎之GraphiteMergeTree详细解析
GraphiteMergeTree是ClickHouse用于优化Graphite数据存储和汇总的表引擎,适合需要瘦身和高效查询Graphite数据的开发者。它基于MergeTree,减少存储空间并提升查询效率。创建表时需包括Path、Time、Value和Version列。配置涉及pattern、regexp、function和retention,用于指定聚合函数和数据保留规则。文章还提供了建表语句示例和相关资源链接。
61 1
|
2月前
|
并行计算 Java 开发者
解析Java中的Lambda表达式用法
解析Java中的Lambda表达式用法
|
2月前
|
JavaScript
js 解析和操作树 —— 获取树的深度、提取并统计树的所有的节点和叶子节点、添加节点、修改节点、删除节点
js 解析和操作树 —— 获取树的深度、提取并统计树的所有的节点和叶子节点、添加节点、修改节点、删除节点
64 0

热门文章

最新文章

推荐镜像

更多