meng-meng(萌萌)
荷焙挚掖IQueryable FromExpression(Expression expression)看着好像很复杂的样子。其实不咱们来拆解一下1、TResult 是类型参数泛型的知识点没忘吧这里其实指的就是实体类型比如你的爱狗 Dog。2、这个方法返回 IQueryable 类型说明允许你使用 LINQ 查询。3、重点理解其参数——Expression 表达有个万能规律可以把与 TDelegate 类型兼容的 lambda 表达式直接赋值给 Expression 变量。即这个 FromExpression 方法可以使用以下 lambda 表达式作为参数() [返回 IQueryable]这个委托的意思就是它单身狗无参数一枚但可以生产 IQueryable 对象。哦说了一大堆还没说这个方法到底有啥毛用。它的用处就是你可以指定一个表达式让 EF 一开始就返回筛选过的查询。在 DbContext 的派生类中声明 DbSet 类型的带 get set 的公共属性这种生成首个查询根查询是最常用的方案这个相信大伙们都很熟了EF Core 最基础操作老周就不多介绍了。假如你要对查询的初始数据做筛选那么按照 DbSet 的方案要先执行一下 SELECT **** FROM #$$#* 语句然后再执行 SELECT **** FROM *^$ WHERE xxxxx我还没操作数据呢就执行了两次 SELECT 语句了。所以说如果你一开始并不打算提取所有数据那么直接从一开始就执行 SELECT **** FROM xxxx WHERE yyyy 多好何必多浪费一条 SQL 语句还有一种使用场景你的数据不是从某个表 SELECT 出来的而是从一个表值函数返回的这种情况也要借助 FromExpression 方法。不知道老周以上说明你是否明白不明白没关系咱们实战一下你就懂了。咱们先定义的实体复制代码////// 妖书实体///public class Book{////// 标识 主键///public Guid BookId { get; set; }////// 书名///public string Title { get; set; } string.Empty;////// 简介///public string? Description { get; set; }////// 作者///public string Author { get; set; } string.Empty;}复制代码然后继承 DbContext 类常规操作。复制代码public class MyDbContext : DbContext{protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){optionsBuilder.UseSqlServer(Server.\\TEST;Databasemydb;Integrated SecurityTrue;Trust Server CertificateTrue);// 配置日志//.LogTo(log Debug.WriteLine(log));}protected override void OnModelCreating(ModelBuilder modelBuilder){modelBuilder.Entity(t {t.ToTable(books, tb {tb.Property(x x.BookId).HasColumnName(book_id);tb.Property(zz.Title).HasColumnName(title);tb.Property(k k.Description).HasColumnName(desc);tb.Property(f f.Author).HasColumnName(author);}).HasKey(t t.BookId);});}// 以下行现在不需要了//public DbSet Books { get; set; }public IQueryable MyBooks FromExpression(() Set().Where(x x.Author 老周));}复制代码这里不用再定义 DbSet 类型的属性了因为我们要对数据进行筛选重点看 MyBooks 属性的实现public IQueryable MyBooks FromExpression(() Set().Where(x x.Author 老周));Set() 方法的调用会让 DbContext 自动在缓存字典中添加数据集合然后一句 Where 做出筛选上述代码的意思是只查询老周写的妖书其他作者的不考虑。这时候 DbContext 不会发出 select * from xxx SQL 语句所以你不用担心执行多余的 SQL。调用 FromExpression 方法后会使初始查询直接生成 Select * from xxx where ...... 语句只查询一次。现在往 SQL Server 中新建 mydb 数据库并创建 books 表。复制代码CREATE TABLE [dbo].[books] ([book_id] UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,[title] NVARCHAR (35) NOT NULL,[desc] NVARCHAR (100) NULL,[author] NVARCHAR (20) NOT NULL,PRIMARY KEY CLUSTERED ([book_id] ASC));复制代码顺便向表中插入些测试数据。insert into books (title, author, [desc])values (NR语言从盗墓到考古, N张法师, N一套不正经的R语言退隐教程),(N疯言疯语之HTML 6.0, N老周, N提前一个世纪出现的超文本协议),(N程序员风水学, N孙电鹰, N先匪后将的他曾有“东陵大盗”之称在盗掘过程中他学会了用风水理论去Debug项目),(N鸡形机器人编程入门, N老周, N未来由于长期不种植作物人类只能躺在病床上依靠吮吸预制营养液维持生命后有人提出开发鸡形机器人帮助人类进食)现在咱们试一下。using var context new MyDbContext();foreach(Book bk in context.MyBooks){Console.WriteLine(${bk.Author,-10}{bk.Title});}如果日志启用那么你会看到DbContext 从初始化到 foreach 循环访问数据只生成了一条 SQL 语句。SELECT [b].[book_id], [b].[author], [b].[desc], [b].[title]FROM [books] AS [b]WHERE [b].[author] N老周下面来看看另一种应用情形——映射表值函数。先在 SQL Server 中创建一个内联表值函数名为 get_all_books返回表中所有行。CREATE FUNCTION [dbo].[get_all_books]()RETURNS TABLERETURN select * from dbo.books;回到 .NET 项目咱们要映射一下函数。A、先在 DbContext 的派生类中定义一个方法用于映射到函数不需要实现方法体直接抛异常就行。internal IQueryable GetAllBooksMap(){throw new NotSupportedException();}实际上EF Core 并不会真正调用方法只是通过生成表达式树 反射出方法名然后再找到与方法名对应的数据库中的函数罢了。所以方法不需要实现代码。B、OnModelCreating 方法要改一下映射列名的 HasColumnName 方法不能在 ToTable 方法中配置否则表值函数返回的实体不能正确映射。复制代码modelBuilder.Entity(t {t.ToTable(books);t.HasKey(t t.BookId);t.Property(x x.BookId).HasColumnName(book_id);t.Property(z z.Title).HasColumnName(title);t.Property(k k.Description).HasColumnName(desc);t.Property(f f.Author).HasColumnName(author);});复制代码也就是列名映射要在 Property 上配置不能在 TableBuilder 上配置。C、HasDbFunction 映射函数。// 注意数据库中的函数名与类方法不同modelBuilder.HasDbFunction(GetType().GetMethod(nameof(GetAllBooksMap), BindingFlags.NonPublic)!).HasName(get_all_books);这里有个误区很多大伙伴以为这样就完事了然后就开始调用代码了。using var context new MyDbContext();foreach(Book bk in context.GetAllBooksMap()){Console.WriteLine(${bk.Author,-10}{bk.Title});}你以为这样是对的但运行后就是错的。上面不是说了吗GetAllBooksMap 方法是没有实现的你不能直接调用它不能调用不能调用不能调用我们还需要再给 DbContext 的派生类再定义一个方法使用 FromExpression 方法让 GetAllBooksMap 转为表达式树。public IQueryable GetAllBooks(){return this.FromExpression(() GetAllBooksMap());}这么一来GetAllBooksMap() 就成了表达式树EF 不会真的调用它只是获取相关信息再翻译成 SQL。然后这样用using var context new MyDbContext();foreach(Book bk in context.GetAllBooks()){Console.WriteLine(${bk.Author,-10}{bk.Title});}看四条记录就读出来了。image可是你也发现了这TM太麻烦了为了表值函数映射我要封装两个方法成员。其实这里可以把两个方法合成一个public IQueryable GetAllBooks(){return this.FromExpression(() GetAllBooks());}由于是公共方法OnModelCreating 中的 HasDbFunction 代码也可以精简一下。modelBuilder.HasDbFunction(GetType().GetMethod(nameof(GetAllBooks))!).HasName(get_all_books);这时候你又搞不懂了WhatGetAllBooks 方法怎么自己调用了自己不不不没有的事你又忘了FromExpression 只是转换为表达式树并不会真的调用它。所以这样合并后其实代码是这样走的1、访问 context.GetAllBooks() 这时候GetAllBooks 方法确实被调用了是你的代码调用的不是EF调用2、GetAllBooks 方法被你调用后FromExpression 方法被调用3、FromExpression 方法参数中lambda 表达式虽然又引用了一次 GetAllBooks 方法但这一次它不会被调用EF Core 只是用来获取方法名。现在明白了吗对微软官方文档中的示例用的就是这种合并的方法表面上看好像自己调用了自己实则不会。好了今天就水到这里。

相关新闻

正确理解 SqlConnection 的连接池机制

正确理解 SqlConnection 的连接池机制

野渴搅庞MX 是什么? JMX 是 “Java Management Extensions” 的缩写,中文通常称为 “Java 管理扩展”。它是 Java 平台提供的一套标准框架,用于对 Java 应用程序、设备、系统资源进行监控和管理。 JMX 的核心作用包括: 监控 Java …

2026/5/17 9:25:22 阅读更多 →
计算机系统基础16---计算机的基本组成---CPU总线

计算机系统基础16---计算机的基本组成---CPU总线

文章目录 什么是CPU总线?总线的层级结构现代总线技术举例总线的性能指标1、总线宽度2、总线频率3、总线带宽 什么是CPU总线? 总线,简单来说,就是一组用于在计算机组件之间传输数据的公共通信线路。它由一组导线和相关控制电路组成…

2026/5/17 9:25:21 阅读更多 →
计算机毕设java电子相册管理系统 基于SpringBoot的在线相册分享平台设计与实现 基于JavaWeb的个人影像资料管理系统开发

计算机毕设java电子相册管理系统 基于SpringBoot的在线相册分享平台设计与实现 基于JavaWeb的个人影像资料管理系统开发

计算机毕设java电子相册管理系统cj3309(配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。随着移动互联网和数码设备的普及,个人数字影像资料呈现爆炸式增长,…

2026/7/6 16:18:16 阅读更多 →

最新新闻

UE5 FString::Printf 与 Format 实战对比:3种场景下的性能与易用性分析

UE5 FString::Printf 与 Format 实战对比:3种场景下的性能与易用性分析

UE5 FString::Printf 与 Format 深度对比:性能优化与工程实践指南1. 核心机制解析在Unreal Engine的字符串处理体系中,FString::Printf和FString::Format代表着两种截然不同的设计哲学。Printf源自传统C语言的printf风格,采用可变参数和类型占…

2026/7/7 23:34:40 阅读更多 →
基于PIC18LF26K22与压电蜂鸣器的工业警报模块设计

基于PIC18LF26K22与压电蜂鸣器的工业警报模块设计

1. 项目背景与核心需求在工业控制、安防系统和智能家居等领域,清晰可靠的警报系统是不可或缺的基础组件。我最近完成了一个基于EPT-14A4005P压电蜂鸣器和PIC18LF26K22微控制器的通用警报模块开发项目,这个方案能在-40C到85C的宽温范围内稳定工作&#xf…

2026/7/7 23:30:37 阅读更多 →
Poppins字体完整指南:免费开源的多语言几何字体解决方案

Poppins字体完整指南:免费开源的多语言几何字体解决方案

Poppins字体完整指南:免费开源的多语言几何字体解决方案 【免费下载链接】Poppins Poppins, a Devanagari Latin family for Google Fonts. 项目地址: https://gitcode.com/gh_mirrors/po/Poppins 在多语言项目开发中,字体选择常常成为技术团队面…

2026/7/7 23:24:35 阅读更多 →
PyTorch LSTM 多变量多任务预测:3种损失加权策略对比与MAPE优化

PyTorch LSTM 多变量多任务预测:3种损失加权策略对比与MAPE优化

PyTorch LSTM多变量多任务预测:3种损失加权策略对比与MAPE优化实战在工业预测、金融分析和环境监测等场景中,我们经常需要同时预测多个相关变量。传统单任务学习模型需要为每个变量单独训练,不仅效率低下,还忽略了变量间的潜在关联…

2026/7/7 23:22:32 阅读更多 →
IAR EWARM历史版本安装实战:嵌入式产线环境复现指南

IAR EWARM历史版本安装实战:嵌入式产线环境复现指南

1. 为什么老工程师还在用 IAR for ARM?——不是守旧,而是嵌入式开发的现实约束在当下 VS Code CMake GCC 工具链大行其道的年代,你可能很难理解:为什么还有大量工业控制、汽车电子、医疗设备领域的项目,依然死死卡在…

2026/7/7 23:20:32 阅读更多 →
CrewAI vs Agno(原 Phidata)完整深度对比

CrewAI vs Agno(原 Phidata)完整深度对比

CrewAI vs Agno(原 Phidata)完整深度对比两者都是 Python 主流 AI 多智能体框架,但底层设计、核心定位、性能、适用场景完全分化:CrewAI:面向复杂业务团队协作、高抽象声明式编排,主打模拟企业分工做长流程…

2026/7/7 23:20:32 阅读更多 →

日新闻

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

图片浏览是移动应用中最高频的场景之一。从社交应用的照片流到电商平台的商品图集,从旅游应用的景点相册到摄影作品展示——用户对图片浏览的体验要求不断提高:流畅的切换动画、直观的缩略图导航、便捷的收藏操作、自动播放模式。HarmonyOS NEXT ArkUI 虽…

2026/7/7 0:05:16 阅读更多 →
24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V稳压芯片完整选型指南 PW8600 PW75XX PW2815 PW2312B LDODC/DC全方案 一、24V稳压方案概述 24V直流电源在工业自动化、门禁系统、电梯控制、汽车电子、LED驱动、监控设备等场景中应用极广,是最常见的中压直流母线电压。要将24V母线稳定降压至下游MCU、传感器…

2026/7/7 0:05:16 阅读更多 →
RAG+知识图谱混合检索与Graph RAG核心对比

RAG+知识图谱混合检索与Graph RAG核心对比

做企业RAG落地的团队,往往容易卡在一容易踩坑的选型难题: 当需求单纯靠向量RAG搞不定、单纯靠知识图谱也搞不定,必须同时依赖「文本语义理解 实体关系推理」时,到底是做「向量图谱混合检索」就够了,还是必须上「Grap…

2026/7/7 0:07:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/7 14:24:45 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/7 12:34:47 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/7 15:59:06 阅读更多 →

月新闻