从CRUD到高级功能:EF Core在.NET Core中全面应用(四)

初识表达式树

表达式树:是一种可以描述代码结构的数据结构,它由一个节点组成,节点表示代码中的操作、方法调用或条件表达式等,它将代码中的表达式转换成一个树形结构,每个节点代表了代码中的操作例如,如果你有一个简单的C#表达式x => x.Name == "John",EFCore会将其转化为一个表达式树,这里我们可以通过Expression构建表达式树,如下所示:

Exception<Func<Book, bool>> e1 = b => b.Price > 5;
Exception<Func<Book, double>> e2 = (b1,b2) => b1.Price + b2.Price;

查看表达式树:这里我们可以通过断点调试,鼠标放在e1上面,点击右键点击快速监视,点击DebugView可以看到文本可视化工具, 如下所示:

整个表达式树是一个“或”类型的节点,左节点(Left)是b.Price>5的表达式,右节点(Right)是另外一个表达式,而b.Price>5这个表达式又是一个大于类型的节点 ,当然我们也可以看一下e2,通过快速监视可以看到其节点类型是相加类型,左边是b1右边是b2:

总结:Expression对象存储了运算逻辑,它把运算逻辑保存成抽象语法树(AST),可以在运行时动态获取运算逻辑,而普通委托则没有。

构建表达式树

        只有通过代码动态构建表达式树才能更好的发挥表达式树的能力,ParameterExpression、BinaryExpression、MethodCallExpression、ConstantExpression等类几乎都没有提供构造方法,而且所有属性也几乎都是只读的。因此我们一般不会直接创建这些类的实例,而是调用Expression类的Parameter、MakeBinary、Call、Constant等静态方法来生成,这些静态方法我们一般称作创建表达式树的工厂方法,而属性则通过方法参数类设置。

ParameterExpression:表示表达式树中的一个参数,通常用于函数参数或 Lambda 表达式中的参数。

我们不能直接创建 ParameterExpression,而是通过 Expression.Parameter 方法来生成,如下:4

var param = Expression.Parameter(typeof(User), "u");

BinaryExpression:表示两个操作数之间的二元操作,例如加法、减法、比较等。我们可以通过 Expression.MakeBinary 方法来构建。

var left = Expression.Property(param, "Age");
var right = Expression.Constant(18);
var binaryExpression = Expression.MakeBinary(ExpressionType.GreaterThan, left, right);

MethodCallExpression:表示调用方法的表达式。例如,调用 ToString() 方法。我们通过 Expression.Call 来创建它。

var method = Expression.Call(param, typeof(User).GetMethod("ToString"));

ConstantExpression:表示常量的值,通常用于表达式中的常量部分。通过 Expression.Constant 方法来创建。

var constant = Expression.Constant(42);

通过组合这些表达式,我们可以构建一个完整的 Lambda 表达式。例如,构建一个 x => x.Age > 18 的表达式:

var param = Expression.Parameter(typeof(User), "x");
var ageProperty = Expression.Property(param, "Age");
var ageGreaterThan = Expression.Constant(18);
var condition = Expression.GreaterThan(ageProperty, ageGreaterThan);var lambda = Expression.Lambda<Func<User, bool>>(condition, param);

通过组合多个表达式,我们可以构建更复杂的表达式。例如,使用逻辑操作符(AND、OR)来构建复合条件表达式:

var left = Expression.GreaterThan(Expression.Property(param, "Age"), Expression.Constant(18));
var right = Expression.Equal(Expression.Property(param, "Name"), Expression.Constant("John"));
var combined = Expression.AndAlso(left, right);var lambda = Expression.Lambda<Func<User, bool>>(combined, param);

总结:通过使用 Expression 类提供的静态工厂方法(如 Expression.Parameter、Expression.MakeBinary、Expression.Call 等),我们可以动态地构建表达式树。这种方式使得我们能够灵活地生成查询条件或操作逻辑,特别是在需要构建动态查询或条件时非常有用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/68260.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言初阶力扣刷题——349. 两个数组的交集【难度:简单】

1. 题目描述 力扣在线OJ题目 给定两个数组&#xff0c;编写一个函数来计算它们的交集。 示例&#xff1a; 输入&#xff1a;nums1 [1,2,2,1], nums2 [2,2] 输出&#xff1a;[2] 输入&#xff1a;nums1 [4,9,5], nums2 [9,4,9,8,4] 输出&#xff1a;[9,4] 2. 思路 直接暴力…

在Qt中实现点击一个界面上的按钮弹窗到另一个界面

文章目录 步骤 1&#xff1a;创建新窗口类步骤 2&#xff1a;设计窗口的 UI步骤 3&#xff1a;设计响应函数 以下是一个完整的示例&#xff0c;展示在Qt中如何实现在一个窗口中通过点击按钮弹出一个新窗口。 步骤 1&#xff1a;创建新窗口类 假设你要创建一个名为 WelcomeWidg…

StarRocks 安装部署

StarRocks 安装部署 StarRocks端口&#xff1a; 官方《配置检查》有服务端口详细描述&#xff1a; https://docs.starrocks.io/zh/docs/deployment/environment_configurations/ StarRocks架构&#xff1a;https://docs.starrocks.io/zh/docs/introduction/Architecture/ Sta…

二叉树的最大深度(力扣104)

所谓二叉树的最大深度其实也是根节点的最大高度&#xff0c;同时也是该二叉树的高度。那么要解决这个问题&#xff0c;我们该选择哪一种遍历方式呢&#xff1f; 要获取最大高度&#xff0c;我们需要比较节点的左右子树的高度&#xff0c;取较大的那个值返回给父节点。通过不断…

dm8在Linux环境安装精简步骤说明(2024年12月更新版dm8)

dm8在Linux环境安装详细步骤 - - 2025年1月之后dm8 环境介绍1 修改操作系统资源限制2 操作系统创建用户3 操作系统配置4 数据库安装5 初始化数据库6 实例参数优化7 登录数据库配置归档与备份8 配置审计9 创建用户10 屏蔽关键字与数据库兼容模式11 jdbc连接串配置12 更多达梦数据…

kafka-保姆级配置说明(consumer)

bootstrap.servers #deserializer应该与producer保持对应 #key.deserializer #value.deserializer ##fetch请求返回时&#xff0c;至少获取的字节数&#xff0c;默认值为1 ##当数据量不足时&#xff0c;客户端请求将会阻塞 ##此值越大&#xff0c;客户端请求阻塞的时间越长&…

Spring MVC 综合案例

目录 一. 加法计算器 1. 准备工作 2. 约定前后端交互接口 需求分析 接口定义 3. 服务器端代码 4. 运行测试 二. 用户登录 1. 准备工作 2. 约定前后端交互接口 需求分析 接口定义 (1) 登录界面接口 (2) 首页接口 3. 服务器端代码 4. 运行测试 三. 留言板 1. 准备…

神经网络|(一)加权平均法,感知机和神经元

【1】引言 从这篇文章开始&#xff0c;将记述对神经网络知识的探索。相关文章都是学习过程中的感悟和理解&#xff0c;如有雷同或者南辕北辙的表述&#xff0c;请大家多多包涵。 【2】加权平均法 在数学课本和数理统计课本中&#xff0c;我们总会遇到求一组数据平均值的做法…

PostGIS笔记:PostgreSQL 数据库与用户 基础操作

数据库基础操作包括数据模型的实现、添加数据、查询数据、视图应用、创建日志规则等。我这里是在Ubuntu系统学习的数据库管理。Windows平台与Linux平台在命令上几乎无差异&#xff0c;只是说在 Windows 上虽然也能运行良好&#xff0c;但在性能、稳定性、功能扩展等方面&#x…

【精选】基于数据挖掘的招聘信息分析与市场需求预测系统 职位分析、求职者趋势分析 职位匹配、人才趋势、市场需求分析数据挖掘技术 职位需求分析、人才市场趋势预测

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

【Redis】常见面试题

什么是Redis&#xff1f; Redis 和 Memcached 有什么区别&#xff1f; 为什么用 Redis 作为 MySQL 的缓存&#xff1f; 主要是因为Redis具备高性能和高并发两种特性。 高性能&#xff1a;MySQL中数据是从磁盘读取的&#xff0c;而Redis是直接操作内存&#xff0c;速度相当快…

python学opencv|读取图像(四十二)使用cv2.add()函数实现多图像叠加

【1】引言 前序学习过程中&#xff0c;掌握了灰度图像和彩色图像的掩模操作&#xff1a; python学opencv|读取图像&#xff08;九&#xff09;用numpy创建黑白相间灰度图_numpy生成全黑图片-CSDN博客 python学opencv|读取图像&#xff08;四十&#xff09;掩模&#xff1a;三…

vue3 vue2区别

Vue 3 和 Vue 2 之间存在多个方面的区别&#xff0c;以下是一些主要的差异点&#xff1a; 1. 性能改进 Vue 3&#xff1a;在性能上有显著提升&#xff0c;包括更小的包体积、更快的渲染速度和更好的内存管理。Vue 2&#xff1a;性能相对较低&#xff0c;尤其是在大型应用中。…

将 OneLake 数据索引到 Elasticsearch - 第 1 部分

作者&#xff1a;来自 Elastic Gustavo Llermaly 学习配置 OneLake&#xff0c;使用 Python 消费数据并在 Elasticsearch 中索引文档&#xff0c;然后运行语义搜索。 OneLake 是一款工具&#xff0c;可让你连接到不同的 Microsoft 数据源&#xff0c;例如 Power BI、Data Activ…

开源项目Umami网站统计MySQL8.0版本Docker+Linux安装部署教程

Umami是什么&#xff1f; Umami是一个开源项目&#xff0c;简单、快速、专注用户隐私的网站统计项目。 下面来介绍如何本地安装部署Umami项目&#xff0c;进行你的网站统计接入。特别对于首次使用docker的萌新有非常好的指导、参考和帮助作用。 Umami的github和docker镜像地…

两种交换排序算法--冒泡,快速

目录 1.冒泡排序原理 2.快速排序原理 3.冒泡代码实现 4.快速排序代码实现 1.冒泡排序原理 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法&#xff0c;基本思想是通过反复交换相邻的元素&#xff0c;直到整个序列有序。它的名字来源于较大的元素像气泡…

Java程序基础⑪Java的异常体系和使用

目录 1. 异常的概念和分类 1.1 异常的概念 1.2 异常的分类 2. 异常的体系结构 3. 异常的处理 3.1 异常的抛出 3.2 异常的捕获与处理 3.3 异常的处理流程 4. 自定义异常类 4.1 自定义异常类的规则 4.2 自定义异常案例 1. 异常的概念和分类 1.1 异常的概念 在Java中&…

大话特征工程:1.维数灾难与特征轮回

一、维度深渊 公元 2147 年&#xff0c;人类文明进入了数据驱动的超级智能时代。从金融到医疗&#xff0c;从教育到娱乐&#xff0c;所有决策都仰赖“全维计算网络”&#xff08;高维特征空间&#xff09;。这套系统将全球所有信息抽象成数以亿计的多维特征&#xff08…

在docker上部署nacos

一、首先下载nacos的docker镜像 docker pull nacos:2.5.0 二、然后下载nacos的安装包&#xff0c;这里是为了拿到他的配置文件。下载完解压缩后&#xff0c;以备后用 https://download.nacos.io/nacos-server/nacos-server-2.5.0.zip?spm5238cd80.6a33be36.0.0.2eb81e5d7mQ…

libOnvif通过组播不能发现相机

使用libOnvif库OnvifDiscoveryClient类&#xff0c; auto discovery new OnvifDiscoveryClient(QUrl(“soap.udp://239.255.255.250:3702”), cb.Build()); 会有错误&#xff1a; end of file or no input: message transfer interrupted or timed out(30 sec max recv delay)…