尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

C# Web开发教程(四)

C# Web开发教程(四)
📅 发布时间:2026/6/20 14:14:41

EF Core SQL性能优化底层原理之表达式树(Expression Trees)

好的,我们来详细探讨一下表达式树(Expression Trees)在 Entity Framework Core 中的核心作用。

简单来说,表达式树是 EF Core 能够将你的 C# 代码(如 LINQ 查询)翻译成高效 SQL 语句的基石。没有表达式树,EF Core 就无法实现其最核心、最有价值的功能。


核心作用:提供可翻译(Translatable)的查询结构

表达式树的核心作用在于,它不是一个可执行的方法,而是一个数据结构。这个数据结构可以被 EF Core 的查询提供程序(Query Provider,例如 SqlServerQueryProvider) 分析、解读,并最终转换为目标数据库的 SQL 语言。

1. 与委托(Delegate)的关键区别

要理解表达式树,最好先把它和普通的委托(如 Func<T, bool>)对比一下。

  • 使用 Func<T, bool>(委托,即内存中的方法):

    Func<Post, bool> myDelegate = p => p.Title.Contains("EF Core");
    

    这是一个可立即执行的代码。如果你在 DbSet<Post> 上使用 .Where(myDelegate),EF Core 无法看到 p.Title.Contains("EF Core") 这个逻辑。它只能调用这个方法,并得到返回的 true 或 false。结果就是,EF Core 必须从数据库拉取所有 Post 数据到内存中,然后在客户端进行过滤。这在大多数情况下性能极差。

  • 使用 Expression<Func<T, bool>>(表达式树):

    Expression<Func<Post, bool>> myExpression = p => p.Title.Contains("EF Core");
    

    这是一个数据的描述。它不是一个可执行的方法,而是一个可以被遍历和检查的树形结构。EF Core 可以解析这棵树,发现它由以下节点组成:

    • 一个参数 p(类型为 Post)
    • 访问 p 的 Title 属性
    • 调用 String.Contains 方法,参数是 "EF Core"
    • 等等...

    正因为 EF Core 能读懂你的意图,它才能生成对应的 SQL 语句:

    SELECT [p].[Id], [p].[Title], [p].[Content], ...
    FROM [Posts] AS [p]
    WHERE [p].[Title] LIKE N'%EF Core%'
    

    查询在数据库服务器上执行,只返回匹配的结果,效率极高。

2. 实现跨数据库平台的查询翻译

EF Core 支持多种数据库(SQL Server, SQLite, PostgreSQL, MySQL等)。其底层为每个数据库提供了不同的查询提供程序。

  • 表达式树提供了一个公共的、抽象的查询中间语言。
  • 当你编写 LINQ 查询时,EF Core 会将其构建为表达式树。
  • 然后,SQL Server 提供程序会将其翻译成 T-SQL,而 SQLite 提供程序则会将其翻译成 SQLite 的 SQL 方言。

这个过程使得你可以用同一套 C# LINQ 代码与不同的数据库进行交互。

3. 实现高效的延迟执行(Deferred Execution)

著名的 IQueryable<T> 接口(提供 LINQ 查询功能的接口)的核心就是一个表达式树和一个查询提供程序。

IQueryable<Post> query = _context.Posts.Where(p => p.Likes > 10).OrderBy(p => p.CreatedDate);
  • 这行代码并没有立即执行查询。
  • 它只是构建了一个表达式树,将 .Where 和 .OrderBy 操作依次组合起来。
  • 只有当你真正需要数据时(例如调用 .ToList()、.FirstOrDefault() 或 foreach 循环),EF Core 才会将整个表达式树翻译成 SQL 并执行。

这种“组合性”是构建复杂动态查询的基础。

4. 支持动态查询构建

这是表达式树非常强大的一个高级用法。因为表达式树是可以在运行时动态构建和修改的,所以你可以在程序运行时根据用户输入或其他条件来动态创建查询。

示例:根据用户选择动态过滤

// 假设这是用户从前端传递过来的过滤条件
string searchTitle = "Hello";
DateTime? minDate = new DateTime(2023, 1, 1);// 从基础查询开始
IQueryable<Post> query = _context.Posts;// 动态添加 Where 条件
if (!string.IsNullOrEmpty(searchTitle))
{// 动态构建表达式: p => p.Title.Contains(searchTitle)query = query.Where(p => p.Title.Contains(searchTitle));
}if (minDate.HasValue)
{// 动态构建表达式: p => p.CreatedDate >= minDatequery = query.Where(p => p.CreatedDate >= minDate.Value);
}// 最终执行的 SQL 会组合所有条件
var results = query.ToList();

EF Core 会将所有动态添加的条件组合到最终的表达式树中,并生成一个包含所有过滤条件的单一、高效的 SQL 语句。


总结

表达式树在 EF Core 中的作用可以概括为以下几点:

作用 说明
查询翻译 最核心的作用。将 C# LINQ 代码转换为等价的 SQL 语句,确保查询在数据库端执行,而不是在客户端内存中。
提供抽象层 作为公共中间语言,使同一套 LINQ 代码可以跨不同数据库工作。
实现延迟执行 使得 IQueryable 可以组合多次查询操作,最后再统一翻译和执行。
支持动态查询 允许在运行时程序化地构建复杂的查询逻辑,极大提升了灵活性。

简而言之,表达式树是 EF Core 的“翻译官”,它让 C# 语言能够与 SQL 数据库进行高效、无缝的对话。 没有表达式树,LINQ to SQL 之类的 ORM 技术就无法实现其核心价值。

表达式树测试

  • 安装第三方库 Install-Package ExpressionTreeToString实现打印表达式树结构
......
using ExpressionTreeToString;
......
Expression<Func<Article, bool>> res = a => a.Price > 0; // 创建表达式树
Console.WriteLine(res.ToString("Object notation","C#")); // 使用 ExpressionTreeToString 输出表达式树- 结果:var a = new ParameterExpression {Type = typeof(Article),IsByRef = false,Name = "a"
};new Expression<Func<Article, bool>> {NodeType = ExpressionType.Lambda,Type = typeof(Func<Article, bool>),Parameters = new ReadOnlyCollection<ParameterExpression> {a},Body = new BinaryExpression {NodeType = ExpressionType.GreaterThan,Type = typeof(bool),Left = new MemberExpression {Type = typeof(int),Expression = a,Member = typeof(Article).GetProperty("Price")},Right = new ConstantExpression {Type = typeof(int),Value = 0}},ReturnType = typeof(bool)
}

总结

它:

  1. 展示了表达式树的内部结构层次
  2. 揭示了每个表达式节点的各种属性(如 NodeType, Type 等)
  3. 说明了表达式树是如何由多个嵌套表达式组成的
  4. 提供了如何手动构建相同表达式树的"配方"

虽然这个输出不能直接编译执行,但它对于理解表达式树的内部工作原理非常有帮助,特别是在调试复杂表达式或学习表达式树API时

相关新闻

  • HarmonyOS运动开发
  • 【2025-09-09】家庭决策
  • 多变量递归-全排列问题

最新新闻

  • 多智能体AI数据科学家:生物标志物发现的自动化与智能化新范式
  • 大语言模型推理加速:上下文压缩与多令牌预测技术解析
  • 2026太原防水补漏避坑指南:卫生间/厨房/阳台/屋顶/地下室漏水检测维修全攻略,正规施工+透明报价+口碑榜靠谱服务商推荐 - 安佳防水
  • 2026青岛即墨区专业的柜机空调维修服务商推荐榜 - 品牌排行榜
  • 互联网大厂 Java 求职面试:从音视频场景到在线教育的技术探讨
  • AI协同数据科学家:LLM智能体如何自动化发现可穿戴设备生物标志物

日新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号