使用linq语句进行联表查询
假设你有一个父表(例如:汽车),其关联一个子表,例如轮子(一对多)。现在你想对于所有的父表汽车,遍历所有汽车,然后打印出来所有轮子的信息。默认的做法将是:
SELECT CarId FROM Cars;
然后对于每个汽车:
SELECT * FROM Wheel WHERE CarId = ?
这会SELECT 2个表一共N(主表的行数)+1(父表)次,故称为SELECT N+1问题。
考察下面的代码。假设ProvinceMeeting是一个会议表,MeetSign是另外一个会议签到表,ProvinceMeeting和MeetSign是一对多的关系:
不推荐的写法:
var Ids = container.ProvinceMeeting.Select(f => f.Id).ToList(); var SignEntities = container.MeetingSign.ToList(); foreach (var Id in Ids) { var sign = container.MeetingSign.Where(f => f.MeetingId == Id); }
每次循环都会连接数据库,执行一条sql语句,select N + 1问题,很消耗性能。
改善后的写法:
//这是我曾经的写法,先遍历获取主表和所有的子表数据存储在数组中,然后再foreach循环查询取出每个主表对应的子表信息, var Entities = container.ProvinceMeeting.ToList(); var SignEntities = container.MeetingSign.ToList(); foreach (var item in Entities) { var sign = SignEntities.Where(f => f.MeetingId == item.Id); }
我们知道foreach会强制LINQ执行,于是,我们可以想象这也是一个SELECT N+1问题的例子:先获得所有ProvinceMeeting(SELECT * FROM ProvinceMeeting),然后遍历,再去SELECT 表MeetingSign,共SELECT N+1次。(当然这里我把数据都啦取出来,储存在内存中,进行操作相当也查询了两次,但随后我还要遍历循环操作数组)。
解决方法:使用一个匿名对象作为中间表格,预先将两个表join到一起:
最佳写法:
var results = container.ProvinceMeeting.Select(f => new { f.Id, son = f.MeetingSign });
我们对结果添加监听,执行效果如下:
主表和子表对应的关联数据,绑定在了一起,不止代码简单,执行效率也高出了不少!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术