前言

上一篇说完了动态创建表达式树, 这篇来说一说解析表达式树.

我之所以会用到是因为最近开始大量使用 trigger 来维护冗余.

但 trigger 本身并不好维护 (EF Core 也不支持), 于是就有了自己写点简单的翻译的想法.

比如在我项目中会通过这样来表达一个冗余值

builder.HasCrossComputed(e => e.BiddingPrice, e => e.Contracts.Sum(e => e.BiddingPrice)).HasColumnName(BiddingPrice);

意思是 BiddingPrice 这个 column 是 Sum 子表的 BiddingPrice

最终会通过 EF Core Migrations 创建 3 个 trigger 监听子表的 insert, update, delete, 然后 update 父表.

主要参考

腾飞(Jesse)– 由浅入深表达式树(二)遍历表达式树

Expression Visitor

要解析表达式, 我们确实可以一层一层自己递归进去. 毕竟它是二叉树形式嘛.

但是 .NET 已经替我们做好了一个粗糙的轮子. 它叫 ExpressionVisitor

它大概长这样

public class SimpleExpressionVisitor : ExpressionVisitor
{
public class MethodCallInfo
{
public string MethodName { get; set; } = "";
public ReadOnlyCollection<Expression> Arguments { get; set; } = new ReadOnlyCollection<Expression>(new List<Expression>());
}
public List<string> VisitedMemberNames { get; set; } = new();
public List<MethodCallInfo> VisitedMethodCallInfos = new(); protected override Expression VisitMember(MemberExpression node)
{
VisitedMemberNames.Add(node.Member.Name);
return base.VisitMember(node);
} protected override Expression VisitMethodCall(MethodCallExpression node)
{
VisitedMethodCallInfos.Add(new MethodCallInfo {
MethodName = node.Method.Name,
Arguments = node.Arguments,
});
return base.VisitMethodCall(node);
}
}

玩法是这样的, ExpressionVisitor 有一个 Visit 方法. 把 expression 交给这个方法后

它就会开始递归, 然后触发 VisitMethodCall, VisitMember, VisitConstant 等等...

我们通过继承 ExpressionVisitor 然后 override 它的各种方法 (大部分是 protect internal) 来拦截整个递归过程.

拦截后可以通过 StringBuilder 拼接 SQL 语句.

大概长这样

这样

这样

总结

反射, 动态创建表达式树, 解析表达式树, 它们本身代码都不好维护, 但是创造出来的东西绝对会让整个项目的代码易于维护许多.

鼓励大家适当的运用在项目中.

ASP.NET Core C# 反射 & 表达式树 (第四篇)的更多相关文章

  1. ASP.NET Core中使用表达式树创建URL

    当我们在ASP.NET Core中生成一个action的url会这样写: var url=_urlHelper.Action("Index", "Home"); ...

  2. 使用Asp.Net Core MVC 开发项目实践[第四篇:基于EF Core的扩展2]

    上篇我们说到了基于EFCore的基础扩展,这篇我们讲解下基于实体结合拉姆达表达式的自定义更新以及删除数据. 先说下原理:其实通过实体以及拉姆达表达式生成SQL语句去执行 第一种更新扩展: 自定义更新字 ...

  3. ASP.NET Core Web开发学习笔记-1介绍篇

    ASP.NET Core Web开发学习笔记-1介绍篇 给大家说声报歉,从2012年个人情感破裂的那一天,本人的51CTO,CnBlogs,Csdn,QQ,Weboo就再也没有更新过.踏实的生活(曾辞 ...

  4. 从零开始实现ASP.NET Core MVC的插件式开发(四) - 插件安装

    标题:从零开始实现ASP.NET Core MVC的插件式开发(四) - 插件安装 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/11260750. ...

  5. C# 反射 表达式树 模糊搜索

    反射实体T,非datetime字段反射获取表达式树   public static Expression<Func<T, bool>> GetSearchExpression& ...

  6. 【无私分享:ASP.NET CORE 项目实战(第十四章)】图形验证码的实现

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 很长时间没有来更新博客了,一是,最近有些忙,二是,Core也是一直在摸索中,其实已经完成了一个框架了,并且正在准备在生产环境中 ...

  7. ASP.NET Core 中的依赖注入 [共7篇]

    一.控制反转(IoC) ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了 ...

  8. ASP.NET Core 快速入门【第二弹-实战篇】

    上篇讲了asp.net core在linux上的环境部署.今天我们将做几个小玩意实战一下.用到的技术和工具有mysql.websocket.AngleSharp(爬虫html解析).nginx多站点部 ...

  9. 使用 ASP.NET Core MVC 创建 Web API(四)

    使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...

  10. 使用Asp.Net Core MVC 开发项目实践[第五篇:缓存的使用]

    项目中我们常常会碰到一些数据,需要高频率用到但是又不会频繁变动的这类,我们就可以使用缓存把这些数据缓存起来(比如说本项目的导航数据,帖子频道数据). 我们项目中常用到有Asp.Net Core 本身提 ...

随机推荐

  1. Django4全栈进阶之路24 项目实战(报修类型表):CKEditor富文本

    CKEditor是一个强大的富文本编辑器,可以用于在网站或应用程序中创建和编辑内容.以下是在安装和使用CKEditor的一般步骤: 安装CKEditor: 下载CKEditor:访问CKEditor官 ...

  2. AT_abc215_d 题解

    洛谷链接&Atcoder 链接 本篇题解为此题较简单做法及较少码量,并且码风优良,请放心阅读. 题目简述 给定 \(N\),\(M\) 及含有 \(N\) 个整数的序列 \(A\). 求 \( ...

  3. C# EF Core 后端代码已定义的用户实体,如何扩展字段?

    注:"2020中国.NET开发者大会"上学习到的开发技巧, 记录下来 1.问题 后端代码已定义的用户实体,如下: public class UserEntity { public ...

  4. Windows11下使用VcXsrv+xfce4实现图形化窗口

    通过 sudo apt-get install xfce4-terminal sudo apt-get install xfce4 sudo service dbus restart 来安装所需要的软 ...

  5. ABC358

    A link -- 点击查看代码 #include<bits/stdc++.h> using namespace std; string s,t; signed main(){ cin & ...

  6. 写写Redis十大类型GEO(地理空间)的常用命令

    又是一个用于处理sql性能的类型,这个类型的核心思想就是把三维的地球变成二维的坐标,再将二维的坐标换成一维的点块,最后将一维的点块转化成base32编码 类型就是zset, 在shell的启动命令后加 ...

  7. 《最新出炉》系列初窥篇-Python+Playwright自动化测试-59 - 判断元素是否显示 - 上篇

    1.简介 有些页面元素的生命周期如同流星一闪,昙花一现.我们也不知道这个元素在没在页面中出现过,为了捕获这一美好瞬间,让其成为永恒.我们就来判断元素是否显示出现过. 在操作元素之前,可以先判断元素的状 ...

  8. CentOS-7离线安装net-tools

    1.下载相关安装包 CentOS-7 所有rpm包的仓库地址:https://vault.centos.org/7.9.2009/os/x86_64/Packages/ net-tools-2.0-0 ...

  9. 【Tutorial C】01 概述

    历史 History 欢迎来到C语言的世界!C语言是一种强大的专业化编程语言,深受业余和专业编程人员的欢迎. 在学习之前先让我们了解和认识它! C语言的原型是A语言(ALGOL 60语言). 1963 ...

  10. 什么样的AI计算框架才是受用户喜欢的?

    说明,本文是个人的一些胡想. 背景: AI计算框架现在从国外的百家争鸣过度到了国内百家争鸣的局面了.在7.8年前的时候,国外的AI计算框架简直是数不胜数,从14.15年前Nvidia公司的显卡需要手动 ...