假设你有一个父表(例如:汽车),其关联一个子表,例如轮子(一对多)。现在你想对于所有的父表汽车,遍历所有汽车,然后打印出来所有轮子的信息。默认的做法将是:

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 });

我们对结果添加监听,执行效果如下:

主表和子表对应的关联数据,绑定在了一起,不止代码简单,执行效率也高出了不少!

使用linq语句进行联表查询的更多相关文章

  1. FreeSql (十七)联表查询

    FreeSql在查询数据下足了功能,链式查询语法.多表查询.表达式函数支持得非常到位. IFreeSql fsql = new FreeSql.FreeSqlBuilder() .UseConnect ...

  2. [慢查优化]联表查询注意谁是驱动表 & 你搞不清楚谁join谁更好时请放手让mysql自行判定

    写在前面的话: 不要求每个人一定理解 联表查询(join/left join/inner join等)时的mysql运算过程: 不要求每个人一定知道线上(现在或未来)哪张表数据量大,哪张表数据量小: ...

  3. (转)MySQL联表查询

    资料源于网络   一.内联结.外联结.左联结.右联结的含义及区别在SQL标准中规划的(Join)联结大致分为下面四种:1.内联结:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结.2 ...

  4. Mysql数据库表排序规则不一致导致联表查询,索引不起作用问题

    Mysql数据库表排序规则不一致导致联表查询,索引不起作用问题 表更描述: 将mysql数据库中的worktask表添加ishaspic字段. 具体操作:(1)数据库worktask表新添是否有图片字 ...

  5. 【转】[慢查优化]联表查询注意谁是驱动表 & 你搞不清楚谁join谁更好时请放手让mysql自行判定

    转自:http://zhengyun-ustc.iteye.com/blog/1942797 写在前面的话: 不要求每个人一定理解 联表查询(join/left join/inner join等)时的 ...

  6. SQL联表查询

    数据库中最最常用的语法----select.简单的select语法很直白: select column from table where expression: 从((from)存储数据的地方(tab ...

  7. sql学习笔记(三)—— 联表查询

    上篇写了一些sql查询的知识,这篇接着写一下有关联表查询的知识. 既然是联表查询,那肯定得多个表啊,所以,我们先创建一个教师表,表名为 teacher,并且向表中插入数据. 准备工作: 创建表语句: ...

  8. MyBatis联表查询

    MyBatis逆向工程主要用于单表操作,那么需要进行联表操作时,往往需要我们自己去写sql语句. 写sql语句之前,我们先修改一下实体类 Course.java: public class Cours ...

  9. Django之model联表:一对多、跨表操作,联表查询

    表结构概述 model.py : class Something(models.Model): name = models.CharField(max_length=32) class UserTyp ...

随机推荐

  1. 1-VScode格式化ESlint-方法(最全最好用方法!)

    1-VScode格式化ESlint-方法(最全最好用方法!)   ESlint:是用来统一JavaScript代码风格的工具,不包含css.html等. 背景: 近来研究前端,然后一直在百度上找VSc ...

  2. LDA-线性判别分析(四)其他几个相关问题

    本来是要调研 Latent Dirichlet Allocation 的那个 LDA 的, 没想到查到很多关于 Linear Discriminant Analysis 这个 LDA 的资料.初步看了 ...

  3. k8s总结(脑图图片)

  4. U盘上安装Ubuntu系统 便捷式系统 - 赖大大

    简单介绍: U盘可以作为电脑的磁盘使用,在U盘上安装Ubuntu系统,只要有电脑,就可以轻松打开自己的系统, 方便又快捷,非常适合出差工作,学习使用. 另外,插入U盘后,需要我们就入电脑的Blos模式 ...

  5. php网页上传文件到Ubuntu服务器(input type=fire)- 赖大大

    直接上代码: <form enctype="multipart/form-data" method="post" action=""& ...

  6. 一张图读懂PBN飞越转弯衔接TF/CF航段计算

    在PBN旁切转弯的基础上,再来看飞越转弯接TF(或CF)航段,保护区结构上有些相似,只是转弯拐角处的保护区边界有“简化”,其余部分是相近的. FlyOver接TF段的标称航迹有一个飞越之后转弯切入航迹 ...

  7. vi/vim使用

    移动光标上:k nk:向上移动n行 9999k或gg可以移到第一行 G移到最后一行下:j nj:向下移动n行左:h nh:向左移动n列右:l nl:向右移动n列 w:光标以单词向前移动 nw:光标向前 ...

  8. R语言实战(四)—— 基本数据管理

    一.基础操作 1.根据数据信息,创建数据框 > manager <- c(1,2,3,4,5) > date <- c("10/24/08","1 ...

  9. JAVAEmail工具错误java.lang.ClassNotFoundException: javax.activation.DataSource

    JDK9以上或JDK6以下使用mail.jar包不加JAF的activation.jar包会抛出该错误!JDK6以上不需要加该jar包: 参考原文 https://stackoverflow.com/ ...

  10. 一个mui扩展插件mui.showLoading加载框【转】

    转:http://ask.dcloud.net.cn/article/12856 写在前面:好像mui目前dialog系列唯独缺少showLoading加载框(加载中)组件,为了统一组件样式和体验,写 ...