购物网站的建设费用/网络营销的推广手段

购物网站的建设费用,网络营销的推广手段,中企动力邮箱app,飞凡网站建设文章目录 前言一、表达式树与委托的区别二、动态构建表达式树示例1示例2示例3高级技巧:表达式合并 三、ExpressionTreeToString安装方法基本用法支持的格式化风格 四、注意事项总结 前言 在 Entity Framework Core 中,表达式树(Expression T…

文章目录

  • 前言
  • 一、表达式树与委托的区别
  • 二、动态构建表达式树
    • 示例1
    • 示例2
    • 示例3
    • 高级技巧:表达式合并
  • 三、ExpressionTreeToString
    • 安装方法
    • 基本用法
    • 支持的格式化风格
  • 四、注意事项
  • 总结


前言

在 Entity Framework Core 中,表达式树(Expression Tree) 是 LINQ 查询的核心机制,它允许将 C# 代码中的查询逻辑转换为 SQL 语句,从而在数据库服务器端高效执行。

一、表达式树与委托的区别

  1. 委托(如 Func<T, bool>
    直接编译为可执行的代码,运行时在内存中过滤数据(客户端评估)。

    Func<House, bool> func = p => p.Owner.Contains("tom");
    var res=dbContext.Houses.Where(exp1).ToList(); // 在客户端过滤!
    
  2. 表达式树(如 Expression<Func<T, bool>>
    保持查询逻辑的抽象语法树结构,EF Core 可将其转换为 SQL服务器端评估)。

    Expression<Func<House, bool>> exp1 = b => b.Owner.Contains("tom");
    var res=dbContext.Houses.Where(exp1).ToList();//生成 SQL:WHERE Owner like '%tom%'
    

二、动态构建表达式树

  1. 当需要根据运行时条件动态生成查询时,手动构建表达式树非常有用。
  2. ParameterExpressionBinaryExpressionMethodCallExpressionConstantExpression等类几乎都没有提供构造方法,而且所有属性也几乎都是只读,因此我们一般不会直接创建这些类的实例,而是调用Expression类的ParameterMakeBinaryCallConstant等静态方法来生成,这些静态方法我们一般称作创建表达式树的工厂方法,而属性则是通过方法参数类设置。
  3. 工厂方法
    加法:Add
    短路与运算:AndAlso
    数组元素访问:ArraryAccess
    方法访问:Call
    三元条件运算符:Condition
    常量表达式:Constant
    类型转换:Convert
    大于运算符:GreaterThan
    小于运算:LessThan
    大于或等于运算符:GreaterThanOrEqual
    创建二元运算:MakeBinary
    不等于运算:NotEqual
    短路或运算:OrElse
    表达式的参数:Parameter

示例1

  1. 动态过滤Owner包含关键字

    using System.Linq.Expressions;
    using (MyDBContext dbContext=new MyDBContext())
    {string name = Console.ReadLine();// 参数表达式:代表实体对象(如 p => ... 中的 p)ParameterExpression param = Expression.Parameter(typeof(House), "p");// 属性访问:p.OwnerMemberExpression nameProperty = Expression.Property(param, "Owner");MethodInfo containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });// 参数值ConstantExpression keywordConstant = Expression.Constant(name);MethodCallExpression nameCondition = Expression.Call(nameProperty, containsMethod, keywordConstant);// 组合为 Lambda 表达式Expression<Func<House, bool>> expr =Expression.Lambda<Func<House, bool>>(nameCondition, param);// 应用查询var query = dbContext.Houses.Where(expr);foreach (var house in query){Console.WriteLine(house.Owner);}
    }
    
  2. 生成的 SQL

    SELECT * FROM Houses WHERE Owner like '%tom%'
    

示例2

  1. 动态过滤价格

    using System.Linq.Expressions;// 参数表达式:代表实体对象(如 p => ... 中的 p)
    ParameterExpression param = Expression.Parameter(typeof(House), "p");// 属性访问:p.Price
    MemberExpression priceProperty = Expression.Property(param, "Price");// 常量值:100
    ConstantExpression constant = Expression.Constant(100.0);// 比较表达式:p.Price > 100
    BinaryExpression priceComparison = Expression.GreaterThan(priceProperty, constant);// 组合为 Lambda 表达式
    Expression<Func<House, bool>> expr = Expression.Lambda<Func<House, bool>>(priceComparison, param);// 应用查询
    var query = dbContext.Houses.Where(expr);
    
  2. 生成的SQL

    SELECT * FROM T_Houses WHERE Price > 100
    

示例3

  1. 组合多个表达式(动态查询中,常需要组合多个条件(如 AND/OR))

    public static Expression<Func<House, bool>> BuildDynamicFilter(string paramOwnerStr,string paramPriceStr,
    string nameKeyword, double? minPrice)
    {ParameterExpression param = Expression.Parameter(typeof(House), "p");Expression finalExpr = Expression.Constant(true); // 初始条件:true// 条件1:名称包含关键字if (!string.IsNullOrEmpty(nameKeyword)){MemberExpression nameProperty = Expression.Property(param, paramOwnerStr);MethodInfo containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });ConstantExpression keywordConstant = Expression.Constant(nameKeyword);MethodCallExpression nameCondition = Expression.Call(nameProperty, containsMethod, keywordConstant);finalExpr = Expression.AndAlso(finalExpr, nameCondition);}// 条件2:价格 >= minPriceif (minPrice.HasValue){MemberExpression priceProperty = Expression.Property(param, paramPriceStr);ConstantExpression minPriceConstant = Expression.Constant(minPrice.Value);BinaryExpression priceCondition = Expression.GreaterThanOrEqual(priceProperty, minPriceConstant);finalExpr = Expression.AndAlso(finalExpr, priceCondition);}return Expression.Lambda<Func<House, bool>>(finalExpr, param);
    }
    
     // 使用:using (MyDBContext dbContext =new MyDBContext()){var filter = BuildDynamicFilter("Owner","Price","Tom", 2000.0);var query = dbContext.Houses.Where(filter);foreach (var house in query){Console.WriteLine(house.Owner);}}
    
  2. 生成的SQL

     SELECT [t].[Id], [t].[Name], [t].[Owner], [t].[Price], [t].[RowVersion]FROM [T_Houses] AS [t]WHERE [t].[Owner] LIKE N'%Tom%' AND [t].[Price] >= 2000.0E0
    

高级技巧:表达式合并

  1. 如果需要组合两个已有的表达式(如 expr1 && expr2),需统一参数。

  2. 示例:合并两个表达式

     public static Expression<Func<T, bool>> CombineAnd<T>(Expression<Func<T, bool>> expr1,Expression<Func<T, bool>> expr2){var param = Expression.Parameter(typeof(T));var body1 = ReplaceParameter(expr1.Body, expr1.Parameters[0], param);var body2 = ReplaceParameter(expr2.Body, expr2.Parameters[0], param);return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(body1, body2),param);}private static Expression ReplaceParameter(Expression expression,ParameterExpression oldParam,ParameterExpression newParam){return new ParameterReplacer(oldParam, newParam).Visit(expression);}class ParameterReplacer : ExpressionVisitor{private readonly ParameterExpression _oldParam;private readonly ParameterExpression _newParam;public ParameterReplacer(ParameterExpression oldParam, ParameterExpression newParam){_oldParam = oldParam;_newParam = newParam;}protected override Expression VisitParameter(ParameterExpression node){return node == _oldParam ? _newParam : node;}}
    
     使用:
    Expression<Func<House, bool>> expr1 = p => p.Owner.Contains("Tom");
    Expression<Func<House, bool>> expr2 = p => p.Price > 2000;
    var combinedExpr = CombineAnd(expr1, expr2);
    var query2 = dbContext.Houses.Where(combinedExpr);
    foreach (var house in query2)
    {Console.WriteLine(house.Owner);
    }
    
  3. 生成的SQL

    SELECT [t].[Id], [t].[Name], [t].[Owner], [t].[Price], [t].[RowVersion]FROM [T_Houses] AS [t]WHERE [t].[Owner] LIKE N'%Tom%' AND [t].[Price] > 2000.0E0
    

三、ExpressionTreeToString

ExpressionTreeToString 是一个第三方库,用于将 LINQ 表达式树(Expression)转换为可读的字符串形式,帮助开发者调试和分析表达式树的结构。
输出的所有代码都是对于工厂方法的调用,且调用工厂方法的时候都省略了Expression类,手动添加Expression或者using static System.Linq.Expressions.Expression;

安装方法

  1. 通过 NuGet 包管理器安装

    Install-Package ExpressionTreeToString
    

基本用法

  1. 示例

    Expression<Func<House, bool>> exp1 = b => b.Owner.Contains("tom");
    Expression<Func<House, bool>> exp2 = b => b.Price > 2000;
    //转换为字符串(支持多种格式化选项)
    //string exprString = expr.ToString("C#", "Dynamic LINQ");//Console.WriteLine(exp1.ToString("Factory methods", "C#"));
    Console.WriteLine(exp2.ToString("Factory methods", "C#"));
    
    //输出结果展示
    // using static System.Linq.Expressions.Expressionvar b = Parameter(typeof(House),"b"
    );Lambda(GreaterThan(MakeMemberAccess(b,typeof(House).GetProperty("Price")),Constant(2000)),b
    )
    

支持的格式化风格

ExpressionTreeToString 提供多种输出格式,方便不同场景使用:

  1. C# 语法风格:ToString(“C#”)
    接近 C# 代码的直观表示。
  2. Visual Basic 语法风格:ToString(“VB”)
    类似 VB 语法。
  3. 表达式树结构:ToString(“Object notation”)
    显示表达式树的节点结构(如 BinaryExpressionParameterExpression)。
  4. 调试视图:ToString(“DebugView”)
    Visual Studio 调试器中表达式树的显示一致。

四、注意事项

  1. 不支持所有 C# 方法:某些方法(如 ToString())无法转换为 SQL,会导致运行时错误。
  2. 调试技巧:通过 query.ToQueryString() 查看生成的 SQL
  3. 性能:表达式树构建在内存中完成,复杂逻辑可能影响启动性能。

总结

通过灵活使用表达式树,可以极大增强 EF Core 查询的灵活性,同时保持高效的服务器端执行。

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

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

相关文章

NVM安装速通使用手册(Windows版)NVM管理node版本命令手册 NVM使用手册

nvm&#xff08;Node Version Manager&#xff09;是一个用于管理Node.js版本的命令行工具。通过nvm&#xff0c;你可以在同一台机器上安装和切换多个Node.js版本&#xff0c;非常适合开发和测试在不同Node.js版本上运行的应用程序 一、安装地址 1. 官方下载&#xff1a; &…

# 基于 OpenCV 的选择题自动批改系统实现

在教育领域&#xff0c;选择题的批改工作通常较为繁琐且重复性高。为了提高批改效率&#xff0c;我们可以利用计算机视觉技术&#xff0c;通过 OpenCV 实现选择题的自动批改。本文将详细介绍如何使用 Python 和 OpenCV 实现一个简单的选择题自动批改系统。 1. 项目背景 选择题…

python黑科技:无痛修改第三方库源码

需求不符合 很多时候&#xff0c;我们下载的 第三方库 是不会有需求不满足的情况&#xff0c;但也有极少的情况&#xff0c;第三方库 没有兼顾到需求&#xff0c;导致开发者无法实现相关功能。 如何通过一些操作将 第三方库 源码进行修改&#xff0c;是我们将要遇到的一个难点…

【服务器操作指南 - GPU 使用与文件传输】轻松掌握 GPU 状态查看和服务器文件传输技巧

0. 引言 在使用服务器时&#xff0c;高效管理 GPU 和文件传输是两项不可或缺的技能。 本指南旨在帮助您快速掌握服务器环境下的 GPU 使用状态监测方法&#xff0c;并简要介绍如何在服务器之间进行文件传输操作。 1. 查看服务器上的 gpu 使用状态 1.1 安装 gpustat 这条指令…

VSCode 市场发现恶意扩展正在传播勒索软件!

在VSCode 市场中发现了两个隐藏着勒索软件的恶意扩展。其中一个于去年 10 月出现在微软商店&#xff0c;但很长时间没有引起注意。 这些是扩展ahban.shiba 和 ahban.cychelloworld&#xff0c;目前已从商店中删除。 此外&#xff0c;ahban.cychelloworld 扩展于 2024 年 10 月…

国信华源携AI+水利创新成果亮相第十五届防汛抗旱信息化技术交流会

直击展会现场 近日&#xff0c;以“人工智能赋能防汛抗旱 融合创新共御极端灾害”为主题的第十五届防汛抗旱信息化技术交流会在河南郑州召开。作为水旱灾害防御领域的专精企业&#xff0c;北京国信华源科技有限公司携自主研发的入户叫应预警系统及覆盖防汛抗旱全链条的智慧化场…

[ C++ ] | C++11 从左值引用到右值引用

&#xff08;目录占位&#xff09; 1. 前言&#xff1a; C 11 是在 C 98 之后又一个变化比较大的标准。为C增加了很多东西&#xff0c;其中有一部分是有用的&#xff0c;有一部分是我自认为作用不是很大东西。这一章呢&#xff1f;我们就来说说C11我&#xff0c;我认为对性能…

基于MCU实现的电机转速精确控制方案:软件设计与实现

本文将详细介绍一篇基于微控制器&#xff08;MCU&#xff09;的电机转速精确控制的软件方案。通过采样PWM信号控制和ADC采样技术&#xff0c;结合PID闭环控制算法&#xff0c;实现了电机转速的高效、稳定调节。以下是软件方案流程图&#xff0c;下文将对其进行展开讲解。 原图太…

AI人工智能-PyCharm的介绍安装应用

下载与安装 创建python项目 项目路径&#xff1a;C:\Users\miloq\Desktop\python_project 配置环境 提前找到conda配置的python-base路径 配置conda环境 运行项目 运行结果

Flink内存模型--flink1.19.1

Flink 的 JobManager 和 TaskManager 在内存分配上有不同的职责和结构。以下是两者的内存分类及详细说明&#xff1a; 一、JobManager 内存分类 JobManager 主要负责作业调度、协调&#xff08;如 Checkpoint 协调&#xff09;、资源管理等&#xff0c;其内存需求相对较低&…

华为数字化转型-方法篇

1 方法篇-3-愿景驱动的数字化转型规划 1.2 业务战略是数字化转型的龙头 1.3 数字时代&#xff0c;企业需要适时地调整业务战略 1.3.1 引入数字化商业模式 引入数字化商业模式包括改变与客户做生意的方式&#xff0c;改变销售的渠道&#xff0c;基于产业互联网重新定位与行 业…

常用的排序算法------练习4

1. 题目 2. 思路和题解 这道题是很经典的荷兰国旗问题&#xff0c;根据题目意思&#xff0c;要对这个数组按照颜色排序&#xff0c;而此时现在的红、白、蓝三个颜色分别对应0&#xff0c;1&#xff0c;2&#xff0c;因此可以想到使用冒泡排序对该数组进行排序。 代码如下&…

传统神经网络、CNN与RNN

在网络上找了很多关于深度学习的资料&#xff0c;也总结了一点小心得&#xff0c;于是就有了下面这篇文章。这里内容较为简单&#xff0c;适合初学者查看&#xff0c;所以大佬看到这里就可以走了。 话不多说&#xff0c;上图 #mermaid-svg-Z3k5YhiQ2o5AnvZE {font-family:&quo…

正则化是什么?

正则化&#xff08;Regularization&#xff09;是机器学习中用于防止模型过拟合&#xff08;Overfitting&#xff09;的一种技术&#xff0c;通过在模型训练过程中引入额外的约束或惩罚项&#xff0c;降低模型的复杂度&#xff0c;从而提高其泛化能力&#xff08;即在未见数据上…

计算机网络——传输层(TCP)

传输层 在计算机网络中&#xff0c;传输层是将数据向上向下传输的一个重要的层面&#xff0c;其中传输层中有两个协议&#xff0c;TCP&#xff0c;UDP 这两个协议。 TCP 话不多说&#xff0c;我们直接来看协议报头。 源/目的端口号&#xff1a;表示数据从哪个进程来&#xff0…

界面控件DevExpress WinForms v25.1 - 人工智能(AI)方面全新升级

DevExpress WinForms拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜…

WinFrom真入门(1)——Windows窗体应用概念

窗体的基本结构 用Winform开发的桌面程序&#xff0c;是在Windows操作系统上运行的&#xff0c;这个不用多说。窗体&#xff08;Form&#xff09;的作用‌&#xff1a;窗体是用户交互的容器&#xff0c;承载按钮、文本框等控件&#xff0c;构成应用程序的界面‌。 在Windows操…

scss预处理器对比css的优点以及基本的使用

本文主要在vue中演示&#xff0c;scss的基本使用。安装命令 npm install sass sass-loader --save-dev 变量 SCSS 支持变量&#xff0c;可将常用的值&#xff08;如颜色、字体大小、间距等&#xff09;定义为变量&#xff0c;方便重复使用和统一修改。 <template><…

Postman 如何高效地转换时间戳?

在 Postman 中&#xff0c;时间戳的处理对于 API 请求和响应的调试和测试至关重要&#xff0c;正确处理时间戳可以确保数据的准确性和一致性&#xff0c;而 Moment 库和原生 JS 是两种常见的处理方式。此外&#xff0c;我们还将介绍 Apifox&#xff0c;它提供了更直观、更简便的…

iptables学习记录

一.四表 filter 表&#xff1a; 主要用于控制数据包的过滤&#xff0c;决定数据包是否允许进出及转发 。比如设置规则允许特定 IP 访问服务器的 SSH 端口&#xff08;22 端口&#xff09;&#xff0c;或禁止某些 IP 访问网站端口&#xff08;80 或 443 端口 &#xff09;。可作…