在ASP.NET中自动合并小图片并使用CSS Sprite显示出来
搜访稍即比 90% 的人细心的大伙伴一定发现了 DbContext 类有一个方法叫 FromExpression它到底干吗用的官方文档中没有专门的介绍只在表值函数映射的例子中看到。咱们先来看看此方法的签名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 只是用来获取方法名。现在明白了吗对微软官方文档中的示例用的就是这种合并的方法表面上看好像自己调用了自己实则不会。好了今天就水到这里。

相关新闻

软件测试之安全测试

软件测试之安全测试

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快一、测试范围管理系统:url、登录框、搜索框、输入框、文件上传、文件下载 客户端:搜索框、输入框、文件上传、系统功能二、测试点密码安全XS…

2026/5/17 7:29:48 阅读更多 →
【影刀RPA】【企业微信】【消除】【小红点】【消息免打扰】

【影刀RPA】【企业微信】【消除】【小红点】【消息免打扰】

前言 有强迫症,见不得有消息堆积,每天好几百条消息提醒,手动点又很烦躁。 官方无支持,手搓一套,解放双手。 点小红点每天消除前一天的,用不上10分钟,所以可以分享使用。 有需要的可以视频三联…

2026/5/17 10:25:55 阅读更多 →
WPF基础到企业应用系列——布局全接触

WPF基础到企业应用系列——布局全接触

敦俑姆罩file,checksec: image main 函数: image hello 函数: image name 中可以保存字符串,因此我们在 name 中输入 /bin/sh,那么我们就可以利用变量 name 的内存地址,得到 system(/bin/sh),从…

2026/5/17 10:25:54 阅读更多 →

最新新闻

侧信道分析实战:基于启发式算法破解DES加密硬件

侧信道分析实战:基于启发式算法破解DES加密硬件

1. 项目概述:当加密算法遇上“旁门左道”在信息安全领域,数据加密标准(DES)虽然已不再是现代高强度应用的首选,但它作为密码学发展史上的里程碑,其设计思想和实现方式至今仍是学习侧信道分析(SC…

2026/7/4 17:18:59 阅读更多 →
Monk AI:面向Kaggle竞赛的声明式机器学习工作流

Monk AI:面向Kaggle竞赛的声明式机器学习工作流

1. 项目概述:用 Monk AI 踏入 Kaggle 竞赛的真实门槛Kaggle 是全球数据科学从业者的练兵场,但对绝大多数刚入门的朋友来说,它更像一座布满迷雾的城堡——你清楚里面藏着模型调优的秘籍、真实业务的数据集、还有能写进简历的金牌徽章&#xff…

2026/7/4 17:18:59 阅读更多 →
大模型竞赛本质是国家能力的系统性较量

大模型竞赛本质是国家能力的系统性较量

1. 为什么这场AI大模型竞赛,本质上是一场“国家能力”的极限拉力赛?你有没有注意过一个现象:2023年之后,全球突然冒出几十家号称“自研大模型”的公司,但真正能稳定发布千亿参数以上基础模型、持续迭代、并支撑起真实产…

2026/7/4 17:16:58 阅读更多 →
Qwen3.5-27B中文大模型选型与工程落地指南

Qwen3.5-27B中文大模型选型与工程落地指南

1. 项目概述:为什么“无脑选 Qwen3.5-27B”不是口号,而是当前中文大模型落地的理性共识最近在多个技术团队做模型选型咨询时,几乎每场讨论都会有人抛出一句:“Qwen3.5系列大模型,无脑选 Qwen3.5-27B”。起初我以为是社…

2026/7/4 17:16:58 阅读更多 →
客户流失预警模型构建与优化实战指南

客户流失预警模型构建与优化实战指南

1. 客户流失风险预警的核心价值 客户流失风险预警(Churn Risk)是客户关系管理中最具挑战性的分析场景之一。我在金融科技行业做用户增长时,曾通过构建流失预警模型将高价值客户留存率提升了37%。这个看似简单的指标背后,隐藏着客户…

2026/7/4 17:14:58 阅读更多 →
VLM自动驾驶评测三把尺:BEV-LLM、VLADBench与DriveBench实战解析

VLM自动驾驶评测三把尺:BEV-LLM、VLADBench与DriveBench实战解析

1. 这不是“自动驾驶变聪明了”,而是我们终于开始认真考它了 最近刷到ICCV 2025那篇标题带感叹号的论文时,我正调试一个BEV感知模块,手边还摊着三份不同团队提交的VLM推理日志。标题里那个“竟靠蒙?”不是修辞,是实测结…

2026/7/4 17:12:57 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻