強大的拉姆表達式轉Sql 類庫 - SqlSugar 隱藏功能之Lambda

使用場景

一、Lambda to sql 一直是ORM中最難的功能之一,若是有現成的解析庫那麼自已寫一個ORM難度將大大下降git

二、經過Lambda做爲KEY進行緩存操做,特別是倉儲模式想要拿到表達式進行通用查詢緩存 則須要用到表達式解析github

三、學習愛好者,若是可以較深刻的理Lambda如何去解成Sql,那麼你對Lambda的理解將會更上一個層次,而不單單在使用上sql

 

優勢

SqlSugar除了有自帶的ORM功能,仍是一款強大的拉姆達解析器  ,而且是市場上獨有 的拉姆達轉Sql類庫 數據庫

SqlSugar不只小巧而且性能很是的好,絕不遜色於Dapper 甚至更加的優秀  ,至於性能別看其餘人的測評 很是不靠譜,自個用了才知道,自個測了才知道緩存

一、高性能  表達式解析速度遠超EF app

二、功能很是完整 ,而且是產品級的解析類庫,支持各類模式的解析函數

三、小巧你只要引用SqlSugar一個DLL就能使用 解析各類數據庫 、支持Sql函數 、支持經常使用原生函數性能

 

安裝

.NET CORE / NET5   Nuget SqlSugarCore學習

.NET 4.5   Nuget SqlSugar spa

.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語句

 

教程案例

一、如何建立 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("不支持");

 

 二、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 ))

 

三、如何解析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] 

 

三、字段名稱的解析

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

 

四、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.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;

 

六、自已動手建立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的解析

一、下面3個用到Where的解析

(o, i, c) => o.Id == i.OrderId&& o.CustomId == c.Id)
 o=>o.id==1
(o,i)=>i.xx==1

 二、下面1個用到列的解析

o=>o.Id

 三、下面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的設計和開發理念,也我十多年開發經驗的彙總

相關文章
相關標籤/搜索