C#表达式目录树系列之1 -- 表达式目录树基本概念

概要

本文主要是帮助读者搞清楚什么是表达式目录树,表达书目录树能做什么,如何创建表达式目录树。后续几篇文章侧重于表达式目录树的具体应用。

表达式目录树是什么

表达式目录树是一种树型结构,它将代码以数据的形式来存储在树的各个节点中,树型结构的每个节点都是一个表达式。

这句话初听很抽象,举个例子。相信大家都使用过ADO.NET中的SqlCommand类,把拼装好的SQL代码作为参数实例化该类,SQL代码就能执行。

事实上,这种方式采用了和表达式目录树同样的设计思想。只不过SQL代码是以字符串的形式存储。这种设计思想带来的好处是我们可以传入任何需要的SQL代码,SqlCommand类的实例都可以去执行,代码具有极强的扩展性。

同样按此设计思想,对于表达式目录树,我们可以根据需要传入任何表达式去执行,以提高代码的可扩展性。

表达式目录树能做什么

根据表达式目录树的定义,我们也就不难看出,表达式目录树可以帮助我们构建任何需要的表达式,然后应用于各种复杂的查询场景。

例如对于EF的查询,我们常常碰到的需求是通过传入的URL,自动解析出查询表达式,进行查询,例如下面的例子

URL 查询表达式
https://xxxxx/students/1 student => student.Id == 1
https://xxxxx/students?Name =Jack student => student.Name == “Jack”
https://xxxxx/students?Sex =1&Name=‘Lily student => student.Sex== 1 && student.Name == “Lily”
https://xxxxx/students?Department=15 student => student.Department== 15

Student类可能有几十个甚至更多的栏位需要支持查询,用户的查询需求又多种多样,各种查询的排列组合可能有上百种,无法像上表那样一一枚举,只能通过URL去动态构建查询表达式。这个时候表达式目录树的优势就发挥出来了。

表达式目录树如何创建

C#中的Expression类提供的一组静态方法的创建表达式目录树,我们以构建查询表达式目录树student => student.Name.StartsWith(“Jack”)为例子,介绍常用的类:

类名 作用
ParameterExpression 构建表达式目录树中的变量,本例即为 => 左侧的student变量
MethodCallExpression 构建表式目录树中的方法调用相关的代码,本例中的StartsWith方法调用表达式就要通过该类创建
MemberExpression 构建表达式目录树中的访问类成员的代码,对应本例中的 student.Name
LambdaExpression 根据构建出的变量和具体的业务表达式,构建Lambda表达式

表达式目录树中代码的执行

表达式目录树在生成后,经过以下三步,即可执行其存储的代码:

  1. 调用Expression.Lambda方法,将生成的目录树student.Name.StartsWith(“Jack”)代码和变量student拼装在一起,生成LambadExpression类的对象
  2. 调用LambadExpression类的Compile()方法,生成委托System.Delegate类型。
  3. 执行用该类型的Invoke方法,执行表达式目录树中存储的代码student.Name.StartsWith(“Jack”),Invoke方法接收一个Student类型的参数。

表达式目录树系列全部文章

  • C#表达式目录树系列之1 – 表达式目录树基本概念
  • C#表达式目录树系列之2 – 常见的表达式目录树的实例
  • C#表达式目录树系列之3 – 为EF查询实现动态OrderBy
  • C#表达式目录树系列之4 – 解决C#泛型约束与无法创建带参数的泛型实例的矛盾
  • C#表达式目录树系列之5 – 动态创建查询表达式

你可能感兴趣的:(.Net,Core,C#基础,c#,后端)