强大的拉姆表达式转Sql 类库 - SqlSugar 隐藏功能之Lambda
使用场景
1、Lambda to sql 一直是ORM中最难的功能之一,如果有现成的解析库那么自已写一个ORM难度将大大降低
2、通过Lambda作为KEY进行缓存操作,特别是仓储模式想要拿到表达式进行通用查询缓存 则需要用到表达式解析
3、学习爱好者,如果能够较深入的理Lambda如何去解成Sql,那么你对Lambda的理解将会更上一个层次,而不仅仅在使用上
优点
SqlSugar除了有自带的ORM功能,还是一款强大的拉姆达解析器 ,并且是市场上独有 的拉姆达转Sql类库
SqlSugar不仅小巧并且性能非常的好,毫不逊色于Dapper 甚至更加的优秀 ,至于性能别看其他人的测评 非常不靠谱,自个用了才知道,自个测了才知道
1、高性能 表达式解析速度远超EF
2、功能非常完整 ,并且是产品级的解析类库,支持各种模式的解析
3、小巧你只要引用SqlSugar一个DLL就能使用 解析各种数据库 、支持Sql函数 、支持常用原生函数
安装
.NET CORE / NET5 Nuget SqlSugarCore
.NET 4.5 Nuget SqlSugar
.NET 4.0 Nuget SqlSuagr 4.x
入门
我们先来看一下例子:
static void Main(string[] args)
{
var age = 11;
Expression<Func<Test, bool>> exp = a => a.id == age; //表达式
SqlServerExpressionContext expContext = new SqlServerExpressionContext();//创建解析对象
expContext.Resolve(exp, ResolveExpressType.WhereSingle);//开始解析
var value = expContext.Result.GetString();//( [id] = @id0 )
var pars = expContext.Parameters;// @id:11
}
下面是调试结果:

通过上面的例子就能够完美的将表达式转换成Sql语句
教程案例
1、如何创建 ExpressionContext 解析对象
我们可以通过SqlSugar.DbType进行区分数据库 并且进行实例化
ExpressionContext expContext=null;
switch (dbtype)
{
case DbType.MySql:
expContext = new MySqlExpressionContext();
break;
case DbType.SqlServer:
expContext = new SqlServerExpressionContext();
break;
case DbType.Sqlite:
expContext = new SqliteExpressionContext();
break;
case DbType.Oracle:
expContext = new OracleExpressionContext();
break;
case DbType.PostgreSQL:
expContext = new PostgreSQLExpressionContext();
break;
case DbType.Dm:
expContext = new DmExpressionContext();
break;
case DbType.Kdbndp:
expContext = new KdbndpExpressionContext();
break;
default:
throw new Exception("不支持");
2、Where条件的解析
基本和写EF一样常用的都会支持
Expression<Func<DataTestInfo2, bool>> exp = it => it.Bool2== b.Value;
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
var pars = expContext.Parameters;
//( [Bool2] = @Bool20 )
我们在写一个Like的例子
Expression<Func<Student, bool>> exp = it => it.Name.Contains(schoolData.Name);
ExpressionContext expContext = new ExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereMultiple);
var value = expContext.Result.GetString();
var pars = expContext.Parameters;
//([it].[Name] like '%'+@MethodConst0+'%')
bool类型的解析是ORM解析的难点中的难点,情况多种多样
Expression<Func<DataTestInfo2, bool>> exp = it => it.Bool1&&it.Bool1;
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
var pars = expContext.Parameters;
//( ( [Bool1]=1 ) AND ( [Bool1]=1 ) )
多样化的bool解释的支持
Expression<Func<Student, bool>> exp = it =>true&& it.Name != null;
ExpressionContext expContext = new ExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
var pars = expContext.Parameters;
//(( 1 = 1 ) AND( [Name] IS NOT NULL ))
多表查询的支持,在多表查询中我们是需要加前缀的比如 我们想要 it.id 而不是id
Expression<Func<Student, bool>> exp = it => (it.Id > 1 && it.Name != name || it.Id == 1) || it.Name == WhereConst.name;
ExpressionContext expContext = new ExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereMultiple);
var value = expContext.Result.GetString();
var pars = expContext.Parameters;
//(((( [it].[Id] > @Id0 ) AND ( [it].[Name] <> @Name1 )) OR ( [it].[Id] = @Id2 )) OR ( [it].[Name] = @Name3 ))
3、如何解析Select
支持实体类解析、查询单个字段解析、匿名对象解析
Expression<Func<DataTestInfo2, DataTestInfo2>> exp =it => new DataTestInfo2() { Bool1=it.Bool1 , Bool2=it.Bool2 };
ExpressionContext expContext = new ExpressionContext();
expContext.IsSingle = false;
expContext.Resolve(exp, ResolveExpressType.SelectSingle);
var selectorValue = expContext.Result.GetString();
var pars = expContext.Parameters;
//[Bool1] AS [Bool1] , [Bool2] AS [Bool2]
Expression<Func<Student, School, object>> exp = (it, school) => new { Name = "a", Id = it.Id / 2, SchoolId = school.Id };
ExpressionContext expContext = new ExpressionContext();
expContext.IsSingle = false;
expContext.Resolve(exp, ResolveExpressType.SelectMultiple);
var selectorValue = expContext.Result.GetString();
// @constant0 AS [Name] , ( [it].[Id] / @Id1 ) AS [Id] , [school].[Id] AS [SchoolId]
3、字段名称的解析
例如orderby(it=>it.Name) 像这种我们就需要拿到Name
Expression<Func<Student, object>> exp = it => it.Name;
ExpressionContext expContext = GetContext();
expContext.Resolve(exp, ResolveExpressType.FieldSingle);
var selectorValue = expContext.Result.GetString();
//Name
统计单 个字段
Expression<Func<Student, object>> exp = it =>SqlFunc.AggregateAvg(it.Id);
ExpressionContext expContext = GetContext();
expContext.Resolve(exp, ResolveExpressType.FieldMultiple);
var selectorValue = expContext.Result.GetString();
//AVG([it].[Id])
4、Sql函数的支持
Expression<Func<Student, bool>> exp = it => (it.Name.Contains("a")? 1:2)==1;
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
var pars = expContext.Parameters;
//(( CASE WHEN ([Name] like '%'+@MethodConst0+'%') THEN @MethodConst1 ELSE @MethodConst2 END ) = @Const3 )
支持的C#函数:
.ToString .Contains .Length
.ToLower .ToUpper .ToSubstring
.Equals .HasValue .Replace
.EndsWith .StartsWith .Trim
.HasValue .Value .AddDay .Date
和常用的Convert.ToInt32等等
SqlFunc.函数
SqlFunc函数下面包含了大量SQL函数
SqlFunc.IF(st.Id > 1)
.Return(st.Id)
.ElseIF(st.Id == 1)
.Return(st.SchoolId).End(st.Id) //等于Case when
5、其它功能
5.1 支持特性比如我表名和实体名不一样我们也可以实现
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.MappingTables.Add(typeof(Student).Name,"OA_STUDENT")
列名也非常容易
SqlServerExpressionContext expContext = new SqlServerExpressionContext();
expContext.MappingColumns.Add("Id","ID",typeof(Student).Name)
5.2 支持子查询
Expression<Func<Test, bool>> exp = a => SqlFunc.Subqueryable<Sutdent>().Where(it => it.testId == a.id).Select(it => it.id) == 1);
var expContext = new SqlServerExpressionContext();
expContext.Resolve(exp, ResolveExpressType.WhereSingle);
var value = expContext.Result.GetString();
var pars = expContext.Parameters;
6、自已动手
通上面的学习你们想写出下面的语法应该相当容易了var oneClass = db.Queryable<Order, OrderItem, Custom>((o, i, c) => o.Id == i.OrderId&& o.CustomId == c.Id))
.Where(o=>o.id==1)
.Where((o,i)=>i.xx==1)
.OrderBy(o=>o.Id)
.Select((o,i,c)=> new ViewOrder
{
Id=SqlFunc.GetSelfAndAutoFill(o.Id),// o.*
CustomName=c.Name //[c].[Name] AS [CustomName]
}).ToList()
实现上面的功能 总共用到Where的解析、列的解析和Select的解析
1、下面3个用到Where的解析
(o, i, c) => o.Id == i.OrderId&& o.CustomId == c.Id)
vo=>o.id==1
(o,i)=>i.xx==1
2、下面1个用到列的解析
o=>o.Id
3、下面1个用到Select的解析
(o,i,c)=> new ViewOrder
{
Id=SqlFunc.GetSelfAndAutoFill(o.Id),// o.*
CustomName=c.Name //[c].[Name] AS [CustomName]
}
源码下载:
你们的赞或者你们的 star 就是 开源者的动力 ,开源不容易和气生财
https://github.com/sunkaixuan/SqlSugar
彩蛋:
下一篇文章 我会介绍如何使用 SqlSugar 实现WebFirst模式开发代码,领先CodeFirst和DbFirst的设计和开发理念,也我十多年开发经验的汇总
强大的拉姆表达式转Sql 类库 - SqlSugar 隐藏功能之Lambda的更多相关文章
- Lambda表达式转SQL语句类库
/* 作者:道法自然 * 个人邮件:myyangbin@sina.cn * 2014-10-1 */ Lambda表达式转SQL语句类库源码下载:http://download.csdn.net/ ...
- 使用CASE表达式替代SQL Server中的动态SQL
原文:使用CASE表达式替代SQL Server中的动态SQL 翻译自: http://www.mssqltips.com/sqlservertip/1455/using-the-case-expre ...
- 在Linq to sql 和 Entity framework 中使用lambda表达式实现left join
在Linq to sql 和 Entity framework 中使用lambda表达式实现left join 我们知道lambda表达式在Linq to sql 和 Entity framework ...
- lambda表达式转换sql
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; usin ...
- C# 表达式树 创建、生成、使用、lambda转成表达式树~表达式树的知识详解
笔者最近学了表达式树这一部分内容,为了加深理解,写文章巩固知识,如有错误,请评论指出~ 表达式树的概念 表达式树的创建有 Lambda法 和 组装法. 学习表达式树需要 委托.Lambda.Func& ...
- C#3.0新增功能08 Lambda 表达式
连载目录 [已更新最新开发文章,点击查看详细] Lambda 表达式是作为对象处理的代码块(表达式或语句块). 它可作为参数传递给方法,也可通过方法调用返回. Lambda 表达式广泛用于: 将 ...
- C# 动态构建表达式树(一)—— 构建 Where 的 Lambda 表达式
C# 动态构建表达式树(一)-- 构建 Where 的 Lambda 表达式 前言 记得之前同事在做筛选功能的时候提出过一个问题:如果用户传入的条件数量不确定,条件的内容也不确定(大于.小于和等于), ...
- SQL Server 2014新功能PPT
本篇文章是我在公司内部分享SQL Server 2014新功能的PPT,在本PPT中我详细描述了SQL Server除了BI方面的新功能,以及提供了大量的测试.希望对大家有帮助. 请点 ...
- C# SQL文件执行器的功能实现
好一段时间没写博客了,这次我们来一起谈谈SQL文件执行器的功能实现,在ERP软件升级时往往在客户端程序更新的同时也要对数据库进行升级,ERP程序开发人员会对数据库升级的执行代码在开发的过程中以SQL文 ...
随机推荐
- 【17】进大厂必须掌握的面试题-50个Angular面试
我们整理了一份主要的Angular面试问题清单,分为三部分: 角度面试问题–初学者水平 角度面试问题–中级 角度面试问题–高级 初学者水平–面试问题 1.区分Angular和AngularJS. 特征 ...
- Javascript的运行效率是原生代码的20%-30%
所以jser们,写代码更仔细些吧. http://www.cnblogs.com/codemood/p/3213459.html
- 使用配置文件方式记录Python程序日志
开发者可以通过三种方式配置日志记录: 调用配置方法的Python代码显式创建记录器.处理程序和格式化程序. 创建日志配置文件并使用fileConfig() 函数读取. 创建配置信息字典并将其传递给di ...
- t分布与t检验的一点理解
最近又遇到了t分布及t检验方面的内容,发现有些地方自己当初没有很明白,就又查了些资料,加深了一下自己的理解,这里也将自己的一些理解记录下来. 1. 理论基础--大数定理与中心极限定理 在 ...
- Elasticsearch 第八篇:数据类型 Array、Nested、Object 的设计与应用
h2.post_title { background-color: rgba(43, 102, 149, 1); color: rgba(255, 255, 255, 1); font-size: 1 ...
- 最全总结 | 聊聊 Python 办公自动化之 Word(中)
1. 前言 上一篇文章,对 Word 写入数据的一些常见操作进行了总结 最全总结 | 聊聊 Python 办公自动化之 Word(上) 相比写入数据,读取数据同样很实用! 本篇文章,将谈谈如何全面读取 ...
- classmethod、staticclassmethod内置装饰器函数
# method 英文是方法的意思 # classmethod 类方法 # 当一个类中的方法中只涉及操作类的静态属性时,此时在逻辑上,我们想要直接通过类名就可以调用这个方法去修改类的静态属性,此时可以 ...
- sqlilab less32-less37
less-32 过滤了单引号,双引号,斜杠,同时设置数据库为GBK编码,可以考虑宽字节注入, 当设置gbk编码后,遇到连续两个字节,都符合gbk取值范围,会自动解析为一个汉字.用脚本来测试下哪些符合 ...
- 精尽MyBatis源码分析 - MyBatis 的 SQL 执行过程(一)之 Executor
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- .Net orm 开源项目 FreeSql 2.0.0(满意的答卷)
写在开头 2018年11月头脑发热到今天,一晃已经两年,当初从舒服区走向一个巨大的坑,回头一看后背一凉. 两年时间从无到有,经历数不清的日夜奋斗(有人问花了多长时间投入,答案:全职x2 + 两年无休息 ...