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 本身提 ...
随机推荐
- LLM-01 大模型 本地部署运行 ChatGLM2-6B-INT4(6GB) 简单上手 环境配置 单机单卡多卡 2070Super8GBx2 打怪升级!
搬迁说明 之前在 CSDN 上发文章,一直想着努力发一些好的文章出来!这篇文章在 2024-04-17 10:11:55 已在 CSDN 发布 写在前面 其他显卡环境也可以!但是最少要有8GB的显存, ...
- 【译】用 GitHub Copilot 提交注释揭开历史的神秘面纱
您是否曾经难以理解一个提交在做什么或者为什么要做?在审查或协作代码更改时,您是否希望有更多的清晰度和上下文?如果您的回答是肯定的,那么您会喜欢 GitHub Copilot 为您所做的--生成提交注释 ...
- 解决Prism中对话框服务中对话框开启时回调函数不会触发的问题
解决办法 新建一个类DialogServiceExtend,然后在再注册 public class DialogServiceExtend : DialogService { public Dialo ...
- 用IO多路复用实现 nginx 静态资源代理(C/Java/Golang)
用IO多路复用实现 nginx 静态资源代理(C/Java/Golang) 效果展示 代理 HTML 代理图片 注意, 静态资源代理基于 HTTP, 可以了解上一篇文章: 几十行代码使用TCP简单实现 ...
- 机器学习:详解是否要使用端到端的深度学习?(Whether to use end-to-end learning?)
详解是否要使用端到端的深度学习? 假设正在搭建一个机器学习系统,要决定是否使用端对端方法,来看看端到端深度学习的一些优缺点,这样就可以根据一些准则,判断的应用程序是否有希望使用端到端方法. 这里是应用 ...
- 概述C#中各种类型集合的特点
在C#中,集合是用于存储和操作一组数据项的数据结构.这些集合通常位于 System.Collections 和 System.Collections.Generic 命名空间中.下面我将概述C#中几种 ...
- 在哲学/自然科学范畴下“推理”(reason about)的类别及解释
注意,本文的解释采用Google大模型(Gemini)的答案. 翻译: 推理是运用逻辑和证据得出结论的过程.它包含批判性地思考一个主题,考虑不同的观点,以及识别事物之间的关系.以下是推理的一些方式: ...
- 标准DQN在测试算法性能时为什么要将探索概率epsilon设置为0.05呢,而不是使用其他探索概率的epsilon-greedy策略或者直接使用greedy探索策略呢?
标准dqn的策略网络参数更新所采用的规则为Q-learning中的更新规则,总所周知的是Q-learning是异策略算法,异策略算法就是行为策略和评估策略(更新所得策略)是不同的. 更新规则: q-l ...
- 如何使用工具下载B站非会员视频(下载B站免费web视频)
最近准备从B站上下载几个web页面上的视频,但是B站的视频又没有提供相关的下载工具,于是找到了一款下载B站视频的工具( you-get ), 该工具不能下载会员版的视频,不能下载收费的视频,不过对于免 ...
- 使用SSH连接局域网内的WSL Ubuntu
参考: https://zhuanlan.zhihu.com/p/586283483 https://www.cnblogs.com/lidabo/p/16855975.html ========== ...