SqlSugar联表查询
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,ca,b,c,d a,b //错误用法a,ca,d |
生成的SQL
SELECT [o].[Id] AS [Id], [cus].[Name] AS [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.[Name] AS [CustomName], o.[Id] AS [Id], o.[Name] AS [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].[Time] AS [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].[Name] AS [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 { get; set; } // ORDER表中的name 主表规则【字段名】 public string CustomName { get; set; }//查询的是Custom中的的name 从表规则【class+字段名】 public string OrderItemPrice { get; set; }//查询的是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.[Name] AS [Name], c.[Name] AS [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 { get; set; } public string Name { get; set; } public int SchoolId { get; set; } [Navigate(NavigateType.OneToOne, nameof(SchoolId))]//一对一 SchoolId是StudentA类里面的 public SchoolA SchoolA { get; set; } //不能赋值只能是null }public class SchoolA{ [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] public int SchoolId { get; set; } public string SchoolName { get; set; }} /*** 在配好导航后可以: 导航对象.具体属性 进行使用 ***///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联表查询的更多相关文章
- .NET 6 跨服务器联表查询
一.大家是否有这个需求 1.跨品种查询 :比如 MYSQL和一个SQLSERVER进行联表查询 ,或者SQLITE和MYSQL进行联表查询 2.跨服务器查询 : A服务器和B服务器查询 如果想同时支持 ...
- [慢查优化]联表查询注意谁是驱动表 & 你搞不清楚谁join谁更好时请放手让mysql自行判定
写在前面的话: 不要求每个人一定理解 联表查询(join/left join/inner join等)时的mysql运算过程: 不要求每个人一定知道线上(现在或未来)哪张表数据量大,哪张表数据量小: ...
- (转)MySQL联表查询
资料源于网络 一.内联结.外联结.左联结.右联结的含义及区别在SQL标准中规划的(Join)联结大致分为下面四种:1.内联结:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结.2 ...
- Mysql数据库表排序规则不一致导致联表查询,索引不起作用问题
Mysql数据库表排序规则不一致导致联表查询,索引不起作用问题 表更描述: 将mysql数据库中的worktask表添加ishaspic字段. 具体操作:(1)数据库worktask表新添是否有图片字 ...
- 【转】[慢查优化]联表查询注意谁是驱动表 & 你搞不清楚谁join谁更好时请放手让mysql自行判定
转自:http://zhengyun-ustc.iteye.com/blog/1942797 写在前面的话: 不要求每个人一定理解 联表查询(join/left join/inner join等)时的 ...
- SQL联表查询
数据库中最最常用的语法----select.简单的select语法很直白: select column from table where expression: 从((from)存储数据的地方(tab ...
- sql学习笔记(三)—— 联表查询
上篇写了一些sql查询的知识,这篇接着写一下有关联表查询的知识. 既然是联表查询,那肯定得多个表啊,所以,我们先创建一个教师表,表名为 teacher,并且向表中插入数据. 准备工作: 创建表语句: ...
- MyBatis联表查询
MyBatis逆向工程主要用于单表操作,那么需要进行联表操作时,往往需要我们自己去写sql语句. 写sql语句之前,我们先修改一下实体类 Course.java: public class Cours ...
- [MySQL] MySQL联表查询的执行顺序优化查询
SELECT t4.orgName, t3.projectName, t3.Partner, t1.type, COUNT(DISTINCT t1.imei) AS count FROM `t_tem ...
- Django之model联表:一对多、跨表操作,联表查询
表结构概述 model.py : class Something(models.Model): name = models.CharField(max_length=32) class UserTyp ...
随机推荐
- Linux CentOS 8 安装DHCP服务
DHCP 如果虚拟机没有 /etc/dhcp/dhcpd.conf 文件,这可能是因为 DHCP 服务器软件包尚未安装,或者安装后配置文件未创建. 要创建 DHCP 服务器配置文件 dhcpd.con ...
- 【python爬虫】bs4遍历、搜索文档树 bs4使用css选择器 selenium基本使用 selenium查找标签 selenium执行js代码
目录 上节回顾 今日内容 0 bs4遍历文档树 1 bs4搜索文档树 1.1 find方法的其他参数 2 css选择器 3 selenium基本使用 4 无界面浏览器 4.1 模拟登录百度 5 sel ...
- vmware中 centos 突然不能联网,ens33丢失,见了鬼了..........
本人笔记本上vmware中centos允许一直很稳定,今天启动centos准备docker打包,结果发现不能联网了!!! ifconfig一下,发现ens33没了,见鬼了吧! 于是一通vmware虚拟 ...
- Python | 使用SVM支持向量机进行鸢尾花分类
运行环境 Python: 3.7.1 库: sklearn (Python的机器学习工具箱) 目的: 根据鸢尾花的四个特征,对三种鸢尾花进行分类 数据(共150行,这里截取前6行,完整数据以及代码的下 ...
- (组合游戏)SG函数与SG定理详解
有一段时间没记录知识类的博客了,这篇博客就说一下SG函数和SG定理吧 SG函数是用于解决博弈论中公平组合游戏(Impartial Combinatorial Games,ICG)问题的一种方法. 什么 ...
- Redis6常用语句
格式:(待补充) /redis-6.2.4/src/redis-cli -h $ip -p $port -a $password [command] #以下ip/port/password根据实际情况 ...
- Java应用架构演变史
垂直应用架构 也叫单体架构.以 MVC 的垂直架构举例,MVC 架构通常分为 3 层,展示层.控制层.模型层.通常基于 MVC 架构开发的应用代码会打成一个 war 包,部署在 Tomcat 等 We ...
- C++模板显示指定类型时使用引用遇到的问题
1.问题 这里我想让模板函数接收int和char类型的参数,并进行相加,显示指定参数类型为int. 第一个调用理论上会自动将char类型强转成int类型,后进行相加: 第二个调用理论上会自动将int类 ...
- 【C++】为什么含有纯虚函数的类无法定义对象
纯虚函数的地址为空,无法分配内存,纯虚成员函数对类是没有意义的,失去了普通类的数据和方法绑定于同一对象中的意义,因此无法构造对象,只能由其派生类继承这些成员函数并实现,才能构造派生类对象. 纯虚成员函 ...
- vscode - Prettier插件 统一代码风格规范,保存自动格式化代码
安装 Prettier - Code formatter prettier安装完毕,使用shift+alt+f就可格式化代码. 如果需要自动保存,要在系统设置中增加"editor.forma ...