ASP.NET Core C# 反射 & 表达式树 (第四篇)
前言
上一篇说完了动态创建表达式树, 这篇来说一说解析表达式树.
我之所以会用到是因为最近开始大量使用 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 父表.
主要参考
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# 反射 & 表达式树 (第四篇)的更多相关文章
- ASP.NET Core中使用表达式树创建URL
当我们在ASP.NET Core中生成一个action的url会这样写: var url=_urlHelper.Action("Index", "Home"); ...
- 使用Asp.Net Core MVC 开发项目实践[第四篇:基于EF Core的扩展2]
上篇我们说到了基于EFCore的基础扩展,这篇我们讲解下基于实体结合拉姆达表达式的自定义更新以及删除数据. 先说下原理:其实通过实体以及拉姆达表达式生成SQL语句去执行 第一种更新扩展: 自定义更新字 ...
- ASP.NET Core Web开发学习笔记-1介绍篇
ASP.NET Core Web开发学习笔记-1介绍篇 给大家说声报歉,从2012年个人情感破裂的那一天,本人的51CTO,CnBlogs,Csdn,QQ,Weboo就再也没有更新过.踏实的生活(曾辞 ...
- 从零开始实现ASP.NET Core MVC的插件式开发(四) - 插件安装
标题:从零开始实现ASP.NET Core MVC的插件式开发(四) - 插件安装 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/11260750. ...
- C# 反射 表达式树 模糊搜索
反射实体T,非datetime字段反射获取表达式树 public static Expression<Func<T, bool>> GetSearchExpression& ...
- 【无私分享:ASP.NET CORE 项目实战(第十四章)】图形验证码的实现
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 很长时间没有来更新博客了,一是,最近有些忙,二是,Core也是一直在摸索中,其实已经完成了一个框架了,并且正在准备在生产环境中 ...
- ASP.NET Core 中的依赖注入 [共7篇]
一.控制反转(IoC) ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了 ...
- ASP.NET Core 快速入门【第二弹-实战篇】
上篇讲了asp.net core在linux上的环境部署.今天我们将做几个小玩意实战一下.用到的技术和工具有mysql.websocket.AngleSharp(爬虫html解析).nginx多站点部 ...
- 使用 ASP.NET Core MVC 创建 Web API(四)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...
- 使用Asp.Net Core MVC 开发项目实践[第五篇:缓存的使用]
项目中我们常常会碰到一些数据,需要高频率用到但是又不会频繁变动的这类,我们就可以使用缓存把这些数据缓存起来(比如说本项目的导航数据,帖子频道数据). 我们项目中常用到有Asp.Net Core 本身提 ...
随机推荐
- EasyBPM进销存之物料管理
本文是EasyBPM平台实现进销存系列中的一篇,主要讲述物料的相关的管理. 在ERP系统中,"物料"一词有着广泛的含义,它是所有产品.半成品.在制品.原材料.配套件.协作件.易耗品 ...
- oeasy教您玩转vim - 19 - 使用标记
使用标记 回忆上节课内容 跳转到行号 200G 设置行号选项 显示行号 :se nu 显示相对行号 :se rnu 如何用命令行跳转 :100 但是我如何有的时候记不住到底跳到多少行 能否做个标记留个 ...
- AT_arc111_a 题解
洛谷连接&Atcoder 链接 题目简述 给定两个数 \(n\) 和 \(m\),输出 \(\left\lfloor\frac{10^n}{m}\right\rfloor \bmod m\) ...
- 集群及分布式定时任务中间件MEE_TIMED
集群及分布式定时任务中间件MEE_TIMED 转载请著名出处:https://www.cnblogs.com/funnyzpc/p/18312521 MEE_TIMED一套开源的定时任务中间件,MEE ...
- Vue 使用Use、prototype自定义全局插件
Vue 使用Use.prototype自定义全局插件 by:授客 QQ:1033553122 开发环境 Win 10 node-v10.15.3-x64.msi 下载地址: https ...
- Python版RNA-seq分析教程:差异表达基因分析
Bulk RNA-seq 分析的一个重要任务是分析差异表达基因,我们可以用 omicverse包来完成这个任务.对于差异表达分析而言,首先,我们可> 以先将 gene_id 改为 gene_na ...
- AppiumDesktop控制手机和安卓模拟器
前言: 本期内容 如何用AppiumDesktop连接安卓手机和安卓模拟器 AppiumDesktop基本参数的获取方法,及如何驱动安卓设备 AppiumDesktop在模拟登陆和爬虫中用到的基本功能 ...
- 【摘译+整理】System.IO.Ports.SerialPort使用注意
远古的一篇博客,内容散落于博文和评论 https://sparxeng.com/blog/software/must-use-net-system-io-ports-serialport C# 和 . ...
- Jmeter函数助手7-timeShift
timeShift函数用于获取移动时间变化后的指定格式时间. Format string for DateTimeFormatter (optional) (default unix timestam ...
- 对比python学julia(第一章)--(第三节)山巅一寺一壶酒
在小学阶段背过圆周率的同学对这节的标题应该不陌生.π(3.14159-)是大家熟悉的普通无理数,但也是非常神秘的一组数字,例如几个世纪以来,埃及考古学家和神秘主义追随者一直痴迷于胡夫金字塔暗藏的圆周率 ...