02020502 EF Core高级02-IQuerable会延迟执行、分部和动态构建IQuerable、IQuerable的复用

news/2025/10/6 11:16:42/文章来源:https://www.cnblogs.com/python-web/p/19127420

02020502 EF Core高级02-IQuerable会延迟执行、分部和动态构建IQuerable、IQuerable的复用

1. IQuerable会延迟执行(视频3-25)

1、测试一下:只查询,但是不遍历IQueryable,查看是否有执行SQL语句。
2、在查询之后、foreach前后分别加上输出语句,查看输出内容的顺序。
3、发现:只有遍历IQueryable的时候才会执行。
1.1 IQuerable使用foreach循环对比
  • 在02020409章5.2节基础上继续
// 1. 使用foreach循环
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;namespace OneToMany
{class Program{static void Main(string[] args){using (MyDbContext ctx = new MyDbContext()){IQueryable<Article> arts = ctx.Articles;foreach (var item in arts){Console.WriteLine(item.Title);}}Console.ReadLine();}}
}控制台输出:
杨中科入选中科院
微软发布.NET 10.0
微软发射微星
中国发射小行星探测器// 查看SQL语句
SELECT t.Id, t.Message, t.Title
FROM T_Articles AS t),
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 2. 不使用foreach循环
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;namespace OneToMany
{class Program{static void Main(string[] args){ using (MyDbContext ctx = new MyDbContext()){IQueryable<Article> arts = ctx.Articles;}Console.ReadLine();}}
}注意,此时看不到SQL语句。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 2. 不使用foreach循环
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;namespace OneToMany
{class Program{static void Main(string[] args){ using (MyDbContext ctx = new MyDbContext()){IQueryable<Article> arts = ctx.Articles;}Console.ReadLine();}}
}注意,此时看不到SQL语句。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;namespace OneToMany
{class Program{static void Main(string[] args){using (MyDbContext ctx = new MyDbContext()){Console.WriteLine("开始查询前");IQueryable<Article> arts = ctx.Articles; // @1 代码先查询Console.WriteLine("开始froeach");foreach (var item in arts) // @1.2 代码后foreach{Console.WriteLine(item.Title);}Console.WriteLine("完成foreach");}Console.ReadLine();}}
}控制台输出:开始查询前
开始froeach // @2.1 日志先foreachSELECT t.Id, t.Message, t.Title // 2.2 日志后查询
FROM T_Articles AS t),杨中科入选中科院
微软发布.NET 10.0
微软发射微星
中国发射小行星探测器
完成foreach说明:
1. SQL的Select语句在“开始froeach”之后。
2. 代码中先查询,后froeach;日志中先foreach再查询。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
总结:只有遍历IQuerable的时候才会执行SQL语句。IQuerable只是构建了一个可以被执行的查询。
1.2 IQuerable简介
1、IQueryable只是代表一个“可以放到数据库服务器去执行的查询”,它没有立即执行,只是“可以被执行”而已。
2、对于IQueryable接口调用非终结方法的时候不会执行查询,而调用终结方法的时候则会立即执行查询。
3、终结方法:遍历、ToArray()、ToList()、Min()、Max()、Count()等;
4、非终结方法:GroupBy()、OrderBy()、Include()、Skip()、Take()等。
5、简单判断:一个方法的返回值类型如果是IQueryable类型,那么这个方法一般就是非终结方法,否则就是终结方法。
1.3 为什么要延迟执行
1、可以在实际执行之前,分步构建IQueryable。
2、比如:定义一个方法根据给定的关键字searchWords来查询匹配的书;如果searchAll参数是true,则书名或者作者名中含有给定的searchWords都匹配,否则只匹配书名;如果orderByPrice参数为true,则按照价格排序,否则就自然排序;upperPrice参数代表价格上限。
void QueryBooks(string searchWords, bool searchAll, bool orderByPrice,double upperPrice)
3、试着传递不同参数,查看生成的SQL的不同。
1.4 分部构建IQuerable
  • 在02020409章5.2节基础上继续
// 分部构建IQuerable
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;namespace OneToMany
{class Program{static void Main(string[] args){using (MyDbContext ctx = new MyDbContext()){IQueryable<Article> arts01 = ctx.Articles.Where(a => a.Id > 1);IQueryable<Article> arts02 = arts01.Skip(2);IQueryable<Article> arts03 = arts02.Take(2);IQueryable<Article> arts04 = arts03.Where(a => a.Title.Contains("微软"));foreach (var item in arts04){Console.WriteLine(item.Title);}}Console.ReadLine();}}
}查看SQL语句:
SELECT [t0].[Id], [t0].[Message], [t0].[Title]
FROM (SELECT [t].[Id], [t].[Message], [t].[Title]FROM [T_Articles] AS [t]WHERE [t].[Id] > CAST(1 AS bigint)ORDER BY (SELECT 1)OFFSET @__p_0 ROWS FETCH NEXT @__p_0 ROWS ONLY
) AS [t0]
WHERE [t0].[Title] LIKE N'%微软%'说明:把一步步返回的数据通过SQL语言串起来了。只要没有执行终结方法,那么可以将生成的SQL语句串起来。
1.5 动态构建IQuerable
  • 在02020409章5.2节基础上继续
// Article.cs
using System.Collections.Generic;namespace OneToMany
{class Article // 文章{public long Id { get; set; }public string Title { get; set; }public string Message { get; set; }public List<Comment> Comments { get; set; } = new List<Comment>(); // 建一个空的list,而不用默认的null。public int Price { get; set; } // 增加价格}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 迁移数据库
PM> add-migration init
Build started...
Build succeeded.
To undo this action, use Remove-Migration.
PM> update-database
Build started...
Build succeeded.
Applying migration '20250926124125_adddog'.
Done.
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// Program.cs传参形式1
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;namespace OneToMany
{class Program{static void Main(string[] args){using (MyDbContext ctx = new MyDbContext()){QueryArticles("微软", true, true, 80);}Console.ReadLine();}static void QueryArticles(string searchWords, bool searchAll, bool orderByPrice, double upperPrice) {using (MyDbContext ctx = new MyDbContext()){IQueryable<Article> arts = ctx.Articles.Where(a => a.Price <= upperPrice);if(searchAll){arts = arts.Where(a => a.Title.Contains(searchWords) || a.Message.Contains(searchWords));}else{arts = arts.Where(a => a.Title.Contains(searchWords));}if(orderByPrice){arts = arts.OrderBy(a => a.Price);}foreach (var item in arts){Console.WriteLine(item.Title);}}}}
}控制台输出:
微软发布.NET 10.0
微软发射微星// 查看SQL语句SELECT t.Id, t.Message, t.Price, t.TitleFROM T_Articles AS tWHERE (CAST(t.Price) AS float) <= @__upperPrice_0) && (((@__searchWords_1 LIKE N'') || (CHARINDEX(@__searchWords_1, t.Title) > 0)) || ((@__searchWords_1 LIKE N'') || (CHARINDEX(@__searchWords_1, t.Message) > 0)))ORDER BY t.Price ASC),
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// Program.cs传参形式2
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;namespace OneToMany
{class Program{static void Main(string[] args){using (MyDbContext ctx = new MyDbContext()){QueryArticles("微软", false, false, 80);}Console.ReadLine();}static void QueryArticles(string searchWords, bool searchAll, bool orderByPrice, double upperPrice) {using (MyDbContext ctx = new MyDbContext()){IQueryable<Article> arts = ctx.Articles.Where(a => a.Price <= upperPrice);if(searchAll){arts = arts.Where(a => a.Title.Contains(searchWords) || a.Message.Contains(searchWords));}else{arts = arts.Where(a => a.Title.Contains(searchWords));}if(orderByPrice){arts = arts.OrderBy(a => a.Price);}foreach (var item in arts){Console.WriteLine(item.Title);}}}}
}控制台输出:
微软发布.NET 10.0
微软发射微星// SQL语句
SELECT t.Id, t.Message, t.Price, t.TitleFROM T_Articles AS tWHERE (CAST(t.Price) AS float) <= @__upperPrice_0) && ((@__searchWords_1 LIKE N'') || (CHARINDEX(@__searchWords_1, t.Title) > 0))),
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
总结:IQuerable的延迟执行特性,使得动态的拼接查询条件变得简单。
1.6 IQuerable总结
  • IQueryable代表一个对数据库中数据进行查询的一个逻辑,这个查询是一个延迟查询。我们可以调用非终结方法向IQueryable中添加查询逻辑,当执行终结方法的时候才真正生成SQL语句来执行查询。
  • 可以实现以前要靠SQL拼接实现的动态查询逻辑。

2. IQuerable的复用(视频3-26)

  • 在本章1.5小结基础上继续
1、IQueryable是一个待查询的逻辑,因此它是可以被重复使用的。
2、IQueryable<Book> books = ctx.Books.Where(b => b.Price <= 8);
Console.WriteLine(books.Count());
Console.WriteLine(books.Max(b=>b.Price));
var books2 = books.Where(b=>b.PubTime.Year>2000);
查看生成的SQL
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;namespace OneToMany
{class Program{static void Main(string[] args){using (MyDbContext ctx = new MyDbContext()){IQueryable<Article> arts = ctx.Articles.Where(a => a.Id > 1);Console.WriteLine(arts.Count());Console.WriteLine(arts.Max(a => a.Price));IQueryable<Article> arts2 = arts.Where(a => a.Title.Contains("微软"));arts.ToList(); // 终结方法}Console.ReadLine();}}
}// SQL语句SELECT COUNT(*)FROM [T_Articles] AS [t]WHERE [t].[Id] > CAST(1 AS bigint)SELECT MAX([t].[Price])FROM [T_Articles] AS [t]WHERE [t].[Id] > CAST(1 AS bigint)
...说明:IQuerable可以复用,在不同的方法里面调用终结方法,或者用IQuerable构建新的IQuerable的时候,IQuerable是可以复用的。

结尾

书籍:ASP.NET Core技术内幕与项目实战

视频:https://www.bilibili.com/video/BV1pK41137He

著:杨中科

ISBN:978-7-115-58657-5

版次:第1版

发行:人民邮电出版社

※敬请购买正版书籍,侵删请联系85863947@qq.com※

※本文章为看书或查阅资料而总结的笔记,仅供参考,如有错误请留言指正,谢谢!※

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

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

相关文章

在 PyCharm 中,环境:bert_env , 执行 import wandb 报错。但是,在CMD窗口,环境:bert_env , 执行 import wandb 正常。

同一个wandb包,使用相同的conda虚拟环境,在pycharm中导入失败,在command窗口中导入成功。 同一个ssl包,使用相同的conda虚拟环境,在pycharm中导入失败,在command窗口中导入成功。在 PyCharm 中,环境:bert_env …

设计网站排行北京有哪些网站建设公司

[html] 当html中使用map标签时,area中coords值如何精确定位呢&#xff1f; 在 area 标签上支持的属性有 shape、coords、href、alt、target、type、download、hreflang、media、rel&#xff1b; coords 值如何精确定位圆形&#xff0c;在绘制一个圆形时&#xff0c;其 shapeci…

libopenssl1_0_0-1.0.2p-3.49.1.x86_64安装教程(RPM包手动安装步骤+依赖解决附安装包下载)

libopenssl1_0_0-1.0.2p-3.49.1.x86_64安装教程(RPM包手动安装步骤+依赖解决附安装包下载)​ ​第一步:先检查下系统环境​ 这包是 ​x86_64 架构的(也就是常见的 64 位 Linux 系统),你得确认自己的系统是 64 位…

Linux_T(Sticky Bit)粘滞位详解 - 详解

Linux_T(Sticky Bit)粘滞位详解 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "M…

和顺网站建设电商推广和网络推广的策略

桥梁模式 定义 桥梁模式&#xff08;Bridge Pattern&#xff09;也叫做桥接模式。 将抽象和显示解耦&#xff0c;使得两者可以独立地变化。 优缺点、应用场景 优点 抽象和实现的解耦。 这是桥梁模式的主要特点&#xff0c;它完全是为了解决继承的缺点而提出的设计模式。优…

P2831 [NOIP 2016 提高组] 愤怒的小鸟 题解

传送门 洛谷 题目大意 每关给你最多18只小猪(后文皆为18只),问你最少用几条过原点抛物线全部干掉。 注意这里 \(m\) 其实没用,因为你要是会算最优解了为啥还需要部分分啊? 思路 \(n\leq18\) ,不是暴搜就是状压。…

t型布局网站怎么做移动网站开发公司

无限网络应用越来越广泛&#xff0c;由此应运而生了许多可以蹭网的软件&#xff0c;家里的网速突然变慢了&#xff0c;也许就是隔壁的小哥哥小姐姐在蹭网络&#xff0c;那么如何避免被蹭网&#xff1f;今天小编给各位小伙伴推荐几款路由器管理软件&#xff0c;发现网络变慢了&a…

网站建设功能要求做男女之间的事情的网站

1.1 APT攻击简介 1.1.1APT攻击概念 网络安全&#xff0c;尤其是Internet互联网安全正在面临前所未有的挑战&#xff0c;这主要就来自于有组织、有特定目标、持续时间极长的新型攻击和威胁&#xff0c;国际上有的称之为APT&#xff08;Advanced Persistent Threat&#xff09;攻…

网站开发公司商业计划书国家备案网查询系统

1 socket本地通信 socket原本是为网络通讯设计的&#xff0c;但后来在socket框架的基础上发展出了一种IPC&#xff08;进程通信&#xff09;机制&#xff0c;即UNIX Domain Socket&#xff0c;专门用来实现使用socket实现的本地进程通信。 本地通信的流程与使用的接口与基于TC…

企顺网网站建设做网站费用上海

文章目录 78. 子集&#xff08;集合的所有子集&#xff09;90. 子集 II&#xff08;集合的所有子集&#xff09;792. 匹配子序列的单词数&#xff08;判断是否为子集&#xff09;500. 键盘行&#xff08;集合的交集&#xff09;409. 最长回文串&#xff08;set&#xff09; 更多…

库存中心(三层库存模型)

目录背景和价值WMS一、货主(Owner)货主(Owner)业务对象的核心属性:3. 库存记录:细化到「SKU+货主+库位」三维度逻辑库存一、逻辑层核心业务对象设计1. 库存主档(LogicalInventory):核心载体参考资料 背景和价…

Valley靶机渗透实战:从凭证复用到Python库劫持

本文详细记录了TryHackMe平台Valley靶机的完整渗透过程,涵盖端口扫描、目录枚举、FTP凭证破解、PCAP分析、SSH登录、UPX脱壳和Python库劫持提权等技术要点。Valley靶机渗透报告 - TryHackMe 本文详细记录了我渗透TryH…

深入解析:IP Search Performance Tests dat/db/xdb/mmdb 结构性能差异对比

深入解析:IP Search Performance Tests dat/db/xdb/mmdb 结构性能差异对比pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-famil…

联盟文明网站建设有新突破建设学校网站需要具备

文章目录 指令和参数筛选器远程指令tasklist参数 windows批处理系列&#xff1a;初步&#x1fa9f;命令行设置 指令和参数 tasklist可以获取当前运行的程序列表。当不加参数时&#xff0c;其返回值包括5列&#xff0c;分别是映像名称&#xff0c;PID&#xff0c;会话名&#…

重庆好的网站制作公司济南seo网站排名优化工具

文 | Flood Sung源 | 知乎前言今年最热门的词汇之一当属内卷了。似乎很多行业都由于份额有限而陷入内卷当中。最火的或许是清华学生的这张图&#xff0c;“骑车写代码”&#xff1a;图片来自网络虽然后来知道是这位同学怕关了屏幕程序就断了&#xff0c;但这不禁让人思考&#…

C++篇:002

C++篇:002$(".postTitle2").removeClass("postTitle2").addClass("singleposttitle");C++篇:002.模板 一、模板概念 函数模板 函数模板的格式: template<typename T1, typename T…

10.05模拟赛反思

打得太差了。 T1 由于限制了 \(60\) 步导致挂掉 \(50 pts\)。写代码的时候不能太想当然了,只是期望每次减半而不是严格的。有时候写代码觉得是对的就写了,但是可能到了很后面才发现有问题,更严重的话根本不知道有问…

MariaDB收购SkySQL增强AI与无服务器能力

开源数据库公司MariaDB重新收购其前子公司SkySQL,整合其具备AI能力的无服务器云数据库平台。此次收购将增强MariaDB Cloud的代理AI功能和向量数据库支持,提升多云部署灵活性。MariaDB收购前子公司SkySQL以增强代理AI…

单片机寄存器的四种主要类型! - 实践

单片机寄存器的四种主要类型! - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mona…

手把手教做网站wordpress媒体库全选

Redis 发展到现在已经有 9 种数据类型了&#xff0c;其中最基础、最常用的数据类型有 5 种&#xff0c;它们分别是&#xff1a;字符串类型、列表类型、哈希表类型、集合类型、有序集合类型&#xff0c;而在这 5 种数据类型中最常用的是字符串类型&#xff0c;所以本文我们先从字…