Join用法

语法糖1、2和3 在Where OrderBy GroupBy Select用法都一样的,他们区别就在JOIN的方式不一样,其它都一样

语法糖1

优点:好理解,5个表以内的联表非常爽,支持功能全

缺点:  联表超过5个以上的表后 (x,b,c...) 会比较难看,语法糖2可以弥补

表和表的左连接  新语法糖  5.0.4.2

//联表查询
var query5 = db.Queryable<Order>()
         .LeftJoin<Custom>   ((o, cus ) => o.CustomId == cus.Id)//多个条件用&&
         .LeftJoin<OrderDetail> ((o, cus, oritem) => o.Id == oritem.OrderId)
         .Where(o => o.Id == 1)  
         .Select((o, cus , oritem) => new ViewOrder { Id = o.Id, CustomName = cus.Name })
         .ToList();  //ViewOrder是一个新建的类,更多Select用法看下面文档
 
               
//内联用 .InnerJoin
//FullJoin 需要高版本才支持用法一样
 
//注意:Join (a,b)=> 别名用法: 
a,b //正确用法
a,b,c
a,b,c,d 
  
a,b //错误用法
a,c
a,d

生成的SQL

SELECT
  [o].[Id] AS [Id],
  [cus].[NameAS [CustomName]
FROM
  [Order] o
  Left JOIN [Custom] cus ON ([o].[CustomId] = [cus].[Id])
  Left JOIN [OrderDetail] oritem ON ([o].[Id] = [oritem].[OrderId])
WHERE
  ([o].[Id] = @Id0)

表和Queryable  JOIN 新语法糖  5.0.4.3

var rigtQueryable = db.Queryable<Custom>()
    .LeftJoin<OrderItem>((o, i) => o.Id == i.ItemId)
        .Select(o => o);
  
var List = db.Queryable<Order>()
    .LeftJoin(rigtQueryable, (c, j) => c.CustomId == j.Id)
    .Select(c => c).ToList(); 
 //SELECT c.* FROM [Order] c Left JOIN 
 //(SELECT o.* FROM [Custom] o Left JOIN [OrderDetail] i ON ( [o].[Id] = [i].[ItemId] )  ) j 
 //ON ( [c].[CustomId] = [j].[Id] )

Queryable和表 JOIN  新语法糖  5.0.4.3

var queryable=db.Queryable<Order>();
var list=db.Queryable(queryable).LeftJoin<OrderDetails>((o,d)=>o.id==d.orderid).Select(o=>o).ToList();

更多套娃用法看嵌套查询:

https://www.donet5.com/Home/Doc?typeId=2354

表和内存集合查询

https://www.donet5.com/Home/Doc?typeId=2315

语法糖2

优点1:这种适合联表比较多的比如5个以上的表JOIN写起来会比较爽

优点2:因为是一个参数更容易封装成方法 例如 Queryable<T,T2>(expression)

优点3:   升级到最新支持Cross Join,用法JoinType.CrossJoin,条件写it=>true

缺点:不支持LeftJoin(queryable) 这种嵌套

单表查询是基于db.Queryable<T>

//生成的Sql: from [Order]
db.Queryable<Order>

联表查询是基于多个T,例如 db.Queryable<T, T2,T3>  3个T就是3表查询

db.Queryable<Order, OrderItem, Custom>((o, i, c) => new JoinQueryInfos(
    JoinType.Left, o.Id == i.OrderId, //左连接 左链接 左联 
    JoinType.Left, o.CustomId == c.Id 
))
.Select((o,i,c)=>new ViewModel{ name=o.Name ..})
.ToList()
 
//3个T代表3个表查询,并且按顺序排列
//Order  o     
//OrderItem i   关系 JoinType.Left, o.Id == i.OrderId
//Custom c     关系 JoinType.Left, o.CustomId == c.Id      
//那么生成的Sql就是
// FROM [Order] o 
// Left JOIN [OrderItem] i ON ( [o].[Id] = [i].[OrderId] )  
// Left JOIN [Custom] c ON ( [o].[CustomId] = [c].[Id] )

因为多个T的原因所以在Where 、 Select 、OrderBy、GroupBy操作上同单表查询稍有差别

常见错误:

数组超过界限  5个T就是4个JOIN , 8个T就是7个JOIN ,不要写多了或者写少了

语法糖3

如果全部是Inner Join可以用这种方式直接联表

var list = db.Queryable<Order, OrderItem, Custom>((o, i, c) => o.Id == i.OrderId&&c.Id == o.CustomId)
                .Select((o,i,c)=>new Class1{ Id=o.Id,Name=o.Name,CustomName=c.Name})
                .ToList(); //Class1是一个新建的类,更多Select用法看下面文档

sql:

SELECT  c.[NameAS [CustomName],
      o.[Id] AS [Id],
      o.[NameAS [Name]       
      FROM [Order] o  ,[OrderDetail]  i ,[Custom]  c  
     WHERE (( [o].[Id] = [i].[OrderId] ) AND ( [c].[Id] = [o].[CustomId] ))

Where用法

注意:写在.Select()之前

.Where(o=>o.id==1) //只用到o这样写就行
.Where((o,i)=>i.xx==1) //如果用到i需要这么写
//更多用法:https://www.donet5.com/Home/Doc?typeId=1184

OrderBy用法

注意:写在.Select()之前

.OrderBy(o=>o.id) //只用到o这样写就行
.OrderBy((o,i)=>i.xx) //如果用到i需要这么写
//更多用法: https://www.donet5.com/Home/Doc?typeId=2312

GroupBy用法

注意:写在.Select()之前

.GroupBy(o=>o.id) //只用到o这样写就行
.GroupBy((o,i)=>i.xx) //如果用到i需要这么写
//更多用法: https://www.donet5.com/Home/Doc?typeId=2243

Select 用法

Select位置:

正常情况后面一般是 .Where(..).OrderBy(..).Select(..).ToList()

如果Where等要写在Select后面应该 用Select(...).MergeTable().Where

别名建议写全,后面方便维扩

例如三表查询:(o,i,c)=>  (不建议 o=> 或者 (o,i)=>)

手动映射

Select写几列 查几列,不多查

//新类
.Select((o,i)=>new 类名{Id=o.Id,Name=o.Name,SchoolName=i.Name}).ToList();
//匿名对象
.Select((o,i)=>new {Id=o.Id,Name=o.Name,SchoolName=i.Name}).ToList();
//更多用法看文档下面

实体自动映射1

语法最美,新功能(5.1.3.35)

 var list4=db.Queryable<SchoolA>()
                .LeftJoin<StudentA>((x, y) => (x.SchoolId == y.SchoolId))
                .Select((x,y) => new UnitView01()
                {
                     Name=x.SchoolName,
                     Count=100
                },
                true)//true表示 其余字段自动映射,根据字段名字
               .ToList();

生成的Sql如下:

SELECT        [x].[ID] AS [id] , --自动
          [x].[TimeAS [Time] , --自动 
          [x].[SchoolName] AS [Name--手动 
          100 as [Count]  --手动
          FROM [SchoolA] x
          Left JOIN StudentA  y  ON ( [x].[SchoolId] =[y].[SchoolId])

实体自动映射2

说明:通过x.*方式实现多表查询

//生成的SQL为 Select o.*, [c].[Name] AS [CustomName]
var oneClass = db.Queryable<Order>()
             .LeftJoin<OrderItem>((o,i)=>o.Id == i.OrderId)
             .LeftJoin<Custom>((o,i,c)=>o.CustomId == c.Id)
             .Where(o=>o.Id>1)
.Select((o,i,c)=> new ViewOrder// 是一个新类
{      
   //Id是o任意一个属性
   Id=o.Id.SelectAll(),   //  等于 o.*   (SelectAll建议用一张表,多表会容易重名)
   CustomName=c.Name   // 等于 [c].[Name] AS [CustomName]
}).ToList()

生成Sql如下

SELECT o.*, [c].[NameAS [CustomName] 
              FROM  [Order] o 
              Left JOIN [OrderItem] i ON ( [o].[Id] = [i].[OrderId] )  
              Left JOIN [Custom] c ON ( [o].[CustomId] = [c].[Id] ) WHERE [o].[Id]>1

实体自动映射3

说明:通过约束实现自动映射

比如一个3表查询 Order 、 OrderItem、Custom

需要注意的是 Select用的是自动填充这样使用方便,高并发的地方还是写成上面那种方式(5.0.5.2性能优化提升)

public class ViewOrder
{
 public string Name { getset; } // ORDER表中的name 主表规则【字段名】
 public string CustomName { getset; }//查询的是Custom中的的name 从表规则【class+字段名】
 public string OrderItemPrice { getset; }//查询的是OrderItem中的name 从表规则【 class+字段名】
}
var viewModel= db.Queryable<Order>()
             .LeftJoin<OrderItem>((o,i)=>o.Id == i.OrderId)
             .LeftJoin<Custom>((o,i,c)=>o.CustomId == c.Id)
              .Select<ViewOrder>().ToList();

sql:

SELECT 
          o.[NameAS [Name],
          c.[NameAS [CustomName],
          i.[Price] AS [OrderItemPrice] 
          FROM [Order] o 
          Left JOIN [OrderItem] i ON ( [o].[Id] = [i].[OrderId] )  
          Left JOIN [Custom] c ON ( [o].[CustomId] = [c].[Id] )

注意:

1.ViewOrder必须每个列都能匹配到字段,否则就无法按规则匹配,保证每个列都正确

2.高并发功能不建议使用,手写的性能肯定高于自动映射

匿名对象自动映射

说明:自动主表赋值  表.*

.Select<dynamic>((st,sc)=> new  
   //id是st任意一个属性
   id=st.Id.SelectAll(), //  st.*  (SelectAll建议只用一张表,不然查询列会有重名)
   SchoolName=sc.Name // Name as  SchoolName
}).ToList()
//Select st.*,[sc].[Name] AS [schoolName]
 
//.SelectAll等同于SqlFunc.GetSelfAndAutoFill是个语法糖

四、导航属性联表

如果有配置过导航, 这个就比较简单了Join都不要写了,懒人可以用

//实体
public class StudentA
{
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int StudentId { getset; }
    public string Name { getset; }
    public int SchoolId { getset; }
    [Navigate(NavigateType.OneToOne, nameof(SchoolId))]//一对一 SchoolId是StudentA类里面的
    public SchoolA SchoolA { getset; } //不能赋值只能是null
  
}
public class SchoolA
{
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int SchoolId { getset; }
    public string SchoolName { getset; }
}
   
/*** 在配好导航后可以: 导航对象.具体属性 进行使用 ***/
 
 
//IncludeLeftJoin 会根据导航生成LeftJoin语句 (IncludeLeftJoin)
var list = db.Queryable<StudentA>()//From StudentA x
         .IncludeLeftJoin(x=>x.SchoolA) // Left Join SchoolA y on x.SchoolId=y.Id
         .Where(x =>x.SchoolA.SchoolName=="北大")//Where y.SchoolName='北大'
         .ToList();
 
  
//没有IncludeLeftJoin在Where中也可以直接用(SQL是子查询过滤)
 var list = db.Queryable<StudentA>()
         .Where(x =>x.SchoolA.SchoolName=="北大")//导航对象过滤  
         .ToList();
           
//没有IncludeLeftJoin在Select中也可以直接用(SQL是子查询实现)   
var list = db.Queryable<StudentA>()
             .Where(x => x.id>1)  //Where和Select中别名要写一样
             .Select(x =>new 
                name=x.Name,
                SchoolName= x.SchoolA.SchoolName
             }).ToList();
              
//IncludeLeftJoin 会根据导航生成LeftJoin语句 (IncludeLeftJoin)
var list = db.Queryable<StudentA>()
         .IncludeLeftJoin(x=>x.SchoolA) //Left Join SchoolA y on x.SchoolId=y.Id
         .Where(x =>x.SchoolA.SchoolName=="北大")//y.SchoolName='北大'
         .ToList();

更多用法:https://www.donet5.com/Home/Doc?typeId=1188

五、联表查询设置别名

var list1 = db.Queryable<Order>().AS("Order001")
        .LeftJoin<OrderItem>((o,i)=> o.Id == i.OrderId,"OrderItem001")  
        .LeftJoin<Custom>((o, i, c) => c.Id == o.CustomId,"Custom001"
        .Where((o,i,c)=> o.TypeId==1)
        .Select((o,i,c)=>new classA() { oid=o.Id , iname=i.Name })
        .ToList();

六、子查询和嵌套查询

子查询

var list= db.Queryable<Student>()
            .Where(it => SqlFunc.Subqueryable<School>().Where(s =>s.Id==it.Id).Any())
            .ToList();
 
var list= db.Queryable<Student>()
        .Select(st => new{
                     name = st.Name,
                     id = SqlFunc.Subqueryable<School>()
                           .Where(s => s.Id == st.Id)
                           .Select(s => s.Id)
            }).ToList();

更多:https://www.donet5.com/Home/Doc?typeId=2231

嵌套查询

//Queryable联表      
var q11 = db.Queryable<Order>().Where(it => it.Id>1); 
var q22 = db.Queryable<Order>().Where(it => it.Id > 2); 
var q33 = db.Queryable<Order>().Where(it => it.Id > 3);  
var list= q11.LeftJoin(q22, (x, y) => x.Id == y.Id)
        .LeftJoin(q33, (x, y, z) => x.Id == z.Id)
        .ToList();

更多:https://www.donet5.com/Home/Doc?typeId=2354

七、超过12个表的联表

我们可以通用Megetable进行合并成一个表,然后在进行JOIN

db.Queryable<Order>()
    .LeftJoin<OrderItem>((x, y) => x.id == y.ItemId) 
    .LeftJoin.....省略
    .LeftJoin.....省略 
    .....省略
    .Select((x,y,z,.......省略) => new {xid=x.id,yid=y.ItemId}) 
    .MergeTable()//合并   
    .LeftJoin<OrderItem>((x,y)=>x.yid==y.ItemId)// 最后一个表不是匿名对象就行
    .ToList();

SqlSugar联表查询的更多相关文章

  1. .NET 6 跨服务器联表查询

    一.大家是否有这个需求 1.跨品种查询 :比如 MYSQL和一个SQLSERVER进行联表查询 ,或者SQLITE和MYSQL进行联表查询 2.跨服务器查询 : A服务器和B服务器查询 如果想同时支持 ...

  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. [MySQL] MySQL联表查询的执行顺序优化查询

    SELECT t4.orgName, t3.projectName, t3.Partner, t1.type, COUNT(DISTINCT t1.imei) AS count FROM `t_tem ...

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

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

随机推荐

  1. Mac 修改文件默认打开方式

    Mac 播放 swf Flash文件 选中文件,Command+i 打开简介 不过文件图标还没变过来.重新下明天再看看

  2. L1-018 大笨钟 (10分)

    开始天梯赛专项训练 微博上有个自称"大笨钟V"的家伙,每天敲钟催促码农们爱惜身体早点睡觉.不过由于笨钟自己作息也不是很规律,所以敲钟并不定时.一般敲钟的点数是根据敲钟时间而定的,如 ...

  3. 入门篇-其之十一-流程控制之break和continue关键字

    本文中使用到的工具是Intellij IDEA和JDK 8,需要安装两款工具的请查看这两篇教程:点我查看安装JDK8/11/17教程.点我查看安装Intellij IDEA教程. 一.循环的嵌套 和前 ...

  4. 活动回顾|阿里云云原生 Serverless 技术实践营 深圳站回放&PPT下载

    11月24日"阿里云云原生 Serverless 技术实践营"深圳站圆满落幕.活动受众以关注  Serverless 技术的开发者.企业决策人.云原生领域创业者为主,活动形式为演讲 ...

  5. 【有奖体验】AIGC小说创作大赛开启!通义千问X函数计算部署AI助手

    一个 AI 助手到底能做什么? 可以书写小说 可以解析编写代码 可以鼓舞心灵 提供职业建议 还有更多能力需要您自己去探索.接下来我们将花费 5 分钟,基于函数计算X通义千问部署一个 AI 助手,帮你撰 ...

  6. 基于阿里云Serverless函数计算开发的疫情数据统计推送机器人

    一.Serverless函数计算 什么是Serverless? 在<Serverless Architectures>中对 Serverless 是这样子定义的: Serverless w ...

  7. PostMan——安装使用教程(图文详解)

    https://blog.csdn.net/m0_61843874/article/details/123324727 postman使用教程1-安装与使用: https://www.cnblogs. ...

  8. ElementUI - <el-table> 表格 selection 设置的复选框禁止选中某些行

    https://blog.csdn.net/weixin_44198965/article/details/119026054

  9. C#设计模式13——建造者模式的写法

    1. 什么是建造者模式? 建造者模式是一种创建型设计模式,它通过将一个复杂的对象分解为多个简单的对象并按照一定的顺序进行组装而创建出一个复杂的对象.这样可以使得构造过程更加灵活,同时也可以隐藏创建过程 ...

  10. 每天学五分钟 Liunx 0001 | 存储篇:swap

    swap swap ,内存交换空间,它是磁盘上的一块空间,主要作用是为了防止物理内存不足. CPU 从内存中读取数据.当内存的空间不足时, CPU 难以读取到数据,导致程序无法正常工作.所以诞生了 s ...