强大的 Lambda 式转 Sql 类库 - SqlSugar 隐藏功能之 Lambda

栏目: 软件资讯 · 发布时间: 5年前

内容简介:使用场景 1、Lambda to sql 一直是ORM中最难的功能之一,如果有现成的解析库那么自已写一个ORM难度将大大降低 2、通过Lambda作为KEY进行缓存操作,特别是仓储模式想要拿到表达式进行通用查询缓存 则需要用到表达式...

使用场景

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
}  

 下面是调试结果:

强大的 Lambda 式转 Sql 类库 - SqlSugar 隐藏功能之 Lambda

 

 通过上面的例子就能够完美的将表达式转换成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、自已动手创建ORM

通上面的学习你们想写出下面的语法应该相当容易了 

 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)
 o=>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://gitee.com/sunkaixuan/SqlSugar

 

彩蛋:

下一篇文章 我会介绍如何使用 SqlSugar 实现WebFirst模式开发代码,领先CodeFirst和DbFirst的设计和开发理念,也我十多年开发经验的汇总


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

PHP and MySQL Web Development

PHP and MySQL Web Development

Luke Welling、Laura Thomson / Sams / July 25, 2007 / $49.99

Book Description PHP and MySQL Web Development teaches you to develop dynamic, secure, commerical Web sites. Using the same accessible, popular teaching style of the three previous editions, this b......一起来看看 《PHP and MySQL Web Development》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试