一、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語句
咱們能夠經過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("不支持");
基本和寫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 ))
支持實體類解析、查詢單個字段解析、匿名對象解析
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])
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;
通上面的學習大家想寫出下面的語法應該至關容易了
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的設計和開發理念,也我十多年開發經驗的彙總