【Select 语法全解密】.NET开源ORM框架 SqlSugar 系列

系列文章目录

🎀🎀🎀 .NET开源 ORM 框架 SqlSugar 系列 🎀🎀🎀


文章目录


前言

说到 SQL 语句,最常见的也是最重要的两个关键词 莫过于 WhereSelect 两兄弟了。Where关键词主要用作条件筛选,使用频率那是大的不得了,那我们今天给它开个专场,看看ORM 框架里 Select 都有哪些语法。


一、Select 执行位置

正常情况 :应该在最后面, 一般是 .Where(..).OrderBy(..).Select(..).ToList()

特殊情况 :如果 Select 不是最后一个位置,则 Select 要加 MergeTable() 合并成一个表,

csharp 复制代码
Select(...).MergeTable().Where

🍬语法糖

Select(...).MergeTable() 在新版本中可以用:

csharp 复制代码
SelectMergeTable(it=>new xxx(){xx}).Where

二、返回一个字段和多个字段

csharp 复制代码
List<int> listInt=db.Queryable<Student>().Select(it=> it.Id).ToList();//返回一个字段
DataTable list=db.Queryable<Student>().Select(it=>new { id=it.Id,name=it.Name}).ToDataTable();//2个字段 
List<Class1>list=db.Queryable<Student>().Select(it=>new Class1{id=it.Id,name=it.Name}).ToList();//2个字段 
List<dynamic>list=db.Queryable<Student>().Select(it=>(dynamic)new{id=it.Id,name=it.Name}).ToList(); 
 
//动态 
List<int> listInt=db.Queryable<Student>().Select<int>("id").ToList();
List<Order> listInt=db.Queryable<Student>().Select<ViewModel>("id as id, name as name").ToList();

三、单表返回DTO

csharp 复制代码
//返回匿名对象
var dynamic = db.Queryable<Student>().Select<dynamic>().ToList();
//Select * from Student
 
//手动:返回匿名集合 支持跨程序集
List<dynamic> dynamicList = db.Queryable<Student>().Select(it=>(dynamic)new { id=it.id}).ToList();
//Select id as id from Student Select只有一列所以只查一列
 
//手动:返回匿名集合  不能跨程序集用
var dynamic = db.Queryable<Student>().Select(it=> new { id=it.id}).ToList(); 
 
//手动:返回类集合-手动
List<Student> list= db.Queryable<Student>().Select(it=>new  Student{ id=it.id}).ToList();
//Select id as id from Student Select只有一列所以只查一列
 
//自动返回DTO集合: 请升级 5.1.3.2 
var listDto= db.Queryable<Student>().Select<StudentDto>().ToList();//返回List
 
//自动返回DTO : 请升级 5.1.3.35  
var listDto= db.Queryable<Student>()
            .Select(it=>new StudentDto()
             {
                  Count=100 //手动指定一列在自动映射
             },
             true)//true表式开启自动映射
            .ToList();//返回List

四、多表返回DTO

4.1 手动DTO

csharp 复制代码
var newClass= db.Queryable<Student, School, DataTestInfo>((st, sc, di) => new JoinQueryInfos(
    JoinType.Left, st.SchoolId == sc.Id,
    JoinType.Left, st.Name == di.String
)) 
.Select((st,sc,di)=>new ClassName{ name=st.Name,scid=sc.Id })//看这一行就行了
.ToList();//实体转换
 
//指定了2列只查2列
//select  st.name as name  , sc.id as scid

4.2 实体自动映射1

语法最美,新功能(5.1.3.35)

csharp 复制代码
 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 如下:

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])

4.3 实体自动映射2

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

🚨注意Oracle 如果用到 Take 或者 分页 需要改用 ToffsetPage() 替换

csharp 复制代码
//生成的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如下

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

4.4 实体自动映射3

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

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

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

csharp 复制代码
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如下

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. 高并发功能不建议使用,手写的性能肯定高于自动映射。

4.5 匿名对象自动映射

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

🚨注意Oracle 如果用到 Take 或者 分页 需要改用 ToffsetPage() 替换。

csharp 复制代码
.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是个语法糖

五、创建DTO类

这样就能快速拿到 DTO 类的实体字符串比手写要快的多。

csharp 复制代码
string classtring=db.Qureyable<Order>().Select(....).ToClassString("命名空间");

六、多表查一表

csharp 复制代码
var oneClass = 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) => c).ToList();

七、多表返回2表

csharp 复制代码
var twoClass = 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 { o,i}).ToList()

八、双查询结果用法

当我们需要在 select 后在外面在包一层 select ,代码如下。

csharp 复制代码
      var getAll = db.Queryable<Order>()
            .Select(it => new Order
            {
                Id = it.Id * 2,
                Name = it.Name
            })
            .MergeTable()//将上面的操作变成一个表 mergetable
            .GroupBy(it => it.Id)//对表mergetable进行分组
            .Select(it =>new{ id=it.Id }).ToList();//查询mergetable表里面的字段
             
//SELECT `Id` FROM  
//           (  SELECT  
//                    ( `Id` * @Id0 ) AS `Id` , 
//                    `Name` AS `Name` 
//                                    
//                FROM `Order ) MergeTable 
// GROUP BY `Id`
// 参数 @Id0:2

九、Select之后对字段进行C#处理

9.1 方式1 (5.1.4.113-preview+)

只能返回 string 只能是个单参数

csharp 复制代码
    public class UnitTool
    {
        public static string GetName(string name) //定义一个string
        {
            return "name" + 111;
        }
    }
     
  //获取methodInfo    
  var methodInfo = typeof(UnitTool).GetMethod("GetName");
 
 var list8 = db.Queryable<Order>()
   .Select(it => new
   {
       n = it.Name,
       name = SqlFunc.OnlyInSelectConvertToString(it.Name, methodInfo)//只能是select中用
   }).ToList();

9.2 方式2

相对方式1用法麻烦 支持的功能全些。

实体类 :

csharp 复制代码
var list= db.Queryable<Order>().Select(it=>new Order{ 
    Id=it.Id,
    Name=it.Name
    })
    .Mapper(it => { //只能写在Select后面
        it.Name = it.Id + it.Name;//相当于ToList循环赋值
    }).ToList();

匿名对象 :

csharp 复制代码
var list = db.Queryable<Order>().Select(it=>
        (dynamic)new  //转成 dynamic
        { 
            Id=it.Id,
            Name=it.Name
    })
    .Mapper(it => { //只能写在Select后面
        it.Name = it.Id + it.Name;//相当于ToList循环赋值
    }).ToList();

🚨注意 :( dynamic )不要漏了。

十、动态Select

csharp 复制代码
//方式1:多库兼容
var selector= new List<SelectModel>() { 
    new SelectModel(){  FiledName = "id",AsName = "id2",},
    new SelectModel(){ FiledName = "id"} 
    //常量用法
    new SelectModel(){FieldName= "{string}:a",AsName="Name"}};
      
var list=db.Queryable<Order>().Select(selector).ToList();
//SELECT `id` AS `id2` , `id` AS `id` ,@Name as Name FROM `Order`
//更多复杂用法: https://www.donet5.com/Home/Doc?typeId=2421
 
  
//方式2:直接写SQL
var list=db.Queryable<Order>().Select("ID AS id1,id as id").ToList();
 
 
//方式3: 动态表达式 
StaticConfig.DynamicExpressionParserType = typeof(DynamicExpressionParser); //启动时配置
 
var list= db.Queryable<Order>().Select("it", $"it=>new(it.Id as Id, it.Name)", typeof(Order)).ToList();
 
//需要SqlFunc:https://www.donet5.com/Home/Doc?typeId=2569

十一、别名AS用法

csharp 复制代码
Select(it=>new { id1=it.id ,name2 =it.name })
//select id as id1,name as name2

如果是动态看 上面一个标题

十二、返回元组

csharp 复制代码
List<(int Id, string Name)> list
                = db.Queryable<Order>().Select<(int Id, string Name)>("id,name").ToList();

十三、过滤某一个字段

csharp 复制代码
/***单表***/
db.Queryable<Order>().IgnoreColumns(it=>it.Files).ToList();//只支持单表查询
   
   
/***联查***/
//是主表
var leftQuery=db.Queryable<Order>().IgnoreColumns(it=>it.Files);
var list=db.Queryable(leftQuery).LeftJoin<OrderDetails>((o,d)=>o.id==d.orderid).Select(o=>o).ToList();    
  
//是Join的表
var rightQuery= db.Queryable<OrderItem>().IgnoreColumns(it=>it.Files);
var list=db.Queryable<Order>().LeftJoin(rightQuery,(o,d)=>o.Id == d.OrderId).Select(o=>o).ToList();

总结

感觉东西太多了,脑子记不住啊。大家都是一样,只要大概记住有这么个概念就行,等需要的时候再来翻翻笔记。


系列文章目录

🎀💎🎀 .NET开源 ORM 框架 SqlSugar 系列 🎀💎🎀

【开篇】.NET开源 ORM 框架 SqlSugar 系列
【入门必看】.NET开源 ORM 框架 SqlSugar 系列
【实体配置】.NET开源 ORM 框架 SqlSugar 系列
【Db First】.NET开源 ORM 框架 SqlSugar 系列
【Code First】.NET开源 ORM 框架 SqlSugar 系列
【数据事务】.NET开源 ORM 框架 SqlSugar 系列
【连接池】.NET开源 ORM 框架 SqlSugar 系列
【查询目录】.NET开源 ORM 框架 SqlSugar 系列
【查询基础】.NET开源 ORM 框架 SqlSugar 系列
【排序用法】.NET开源 ORM 框架 SqlSugar 系列
【分组去重】.NET开源 ORM 框架 SqlSugar 系列
【联表查询】.NET开源 ORM 框架 SqlSugar 系列
【导航查询】.NET开源 ORM 框架 SqlSugar 系列
【子查询】.NET开源 ORM 框架 SqlSugar 系列
【嵌套查询】.NET开源 ORM 框架 SqlSugar 系列
【配置查询】.NET开源 ORM 框架 SqlSugar 系列
【并集查询】.NET开源 ORM 框架 SqlSugar 系列
【树型查询】.NET开源 ORM 框架 SqlSugar 系列
【表格查询】.NET开源 ORM 框架 SqlSugar 系列
【动态表达式】.NET开源 ORM 框架 SqlSugar 系列
【查询函数】.NET开源ORM框架 SqlSugar 系列
【过滤器】.NET开源 ORM 框架 SqlSugar 系列
【跨库查询、多库查询】.NET开源 ORM 框架
​【报表查询】.NET开源ORM框架 SqlSugar 系列
【Where语法全解密】.NET开源ORM框架 SqlSugar 系列

相关推荐
在路上走着走着2 分钟前
openEuler安装OpenGauss5.0
数据库·gaussdb
余~~1853816280025 分钟前
矩阵碰一碰发视频源码技术解析,支持OEM
数据库·microsoft
张声录11 小时前
【ETCD】【实操篇(十五)】etcd集群成员管理:如何高效地添加、删除与更新节点
数据库·etcd
天乐敲代码1 小时前
Etcd静态分布式集群搭建
数据库·分布式·etcd
chengma_0909091 小时前
MySQL 数据库连接数查询、配置
数据库·mysql
TDengine (老段)1 小时前
两分钟掌握 TDengine 全部写入方式
大数据·数据库·时序数据库·tdengine·涛思数据
码农君莫笑2 小时前
《信管通低代码信息管理系统开发平台》Windows环境安装说明
服务器·数据库·windows·低代码·c#·bootstrap·.netcore
计算机学长felix2 小时前
基于SpringBoot的“大学生社团活动平台”的设计与实现(源码+数据库+文档+PPT)
数据库·spring boot·后端
木与子不厌2 小时前
微服务自定义过滤器
运维·数据库·微服务