.NET ORM框架 SqlSuagr4.0 功能詳解與實踐【開源】

来源:http://www.cnblogs.com/sunkaixuan/archive/2017/06/18/7043409.html
-Advertisement-
Play Games

SqlSugar 4.0 ORM框架的優勢 為了未來能夠更好的支持多庫分散式的存儲,並行計算等功能,將SqlSugar3.x全部重寫,現有的架構可以輕鬆擴展多庫。 源碼下載: https://github.com/sunkaixuan/SqlSugar 1.性能 性能最好的ORM之一,具有超越Dap ...


SqlSugar 4.0 ORM框架的優勢

為了未來能夠更好的支持多庫分散式的存儲,並行計算等功能,將SqlSugar3.x全部重寫,現有的架構可以輕鬆擴展多庫。

 

源碼下載:

https://github.com/sunkaixuan/SqlSugar

 

1.性能

性能最好的ORM之一,具有超越Dapper的性能 ,走的是EMIT夠構中間語言動態編譯到程式集,完成高性能的實體綁定,達到原生水平。

測試方式用Realease模式,Realease DLL 進行的車輪戰

 

2.功能

除了EF以外可以說的是功能最大的ORM框架

支持 DbFirst、CodeFirst、資料庫維護、鏈式查詢、鏈式更新、鏈式刪除、鏈式插入、實體屬性、複雜模型的查詢、ADO.NET。特別是批量等功能都是貨真價實的並非迴圈操作。

SqlSugar 4.0版本 6月底支持SqlSever的Core版 ,預計7月份支持多庫,8月分開始分散式ORM的開發。 (3.x版本已經支持了4種資料庫,相對穩定功能簡單)

 

3.語法

完美的語法,可以秒殺現有所有ORM框架

 

SqlSugar 4.0 三表查詢並分頁

   int total=0;
var list8 = db.Queryable<Student,School,School>((st,sc,sc2) =>st.SchoolId ==sc.Id&&sc.Id ==sc2.Id)
.Select((st, sc, sc2) =>new{st.Name,st.Id,schoolName = sc.Name})
.ToPageList(1, 2,ref total)

EF 二表查詢並分頁

var queryable = (from a in StudentList
                      join b in SchoolList1
                      on a.Id equals b.Id into b1
                      from b2 in b1.DefaultIfEmpty()
                      select new
                      {
                          a.Id,
                          a.Name,
                          t = b2.Name
 
                      });
var listp = queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
var total = queryable.Count();

從上面的語法可以看出兩者之前的差距,3表查詢比EF2表查詢還要簡潔

 

我們在來看一下條件拼接的例子

 

SqlSugar語法:

var list = db.Queryable<Student>()
                .WhereIF(!string.IsNullOrEmpty(a),it => it.Name == a)
                .WhereIF(!string.IsNullOrEmpty(b), it => it.Name == b).ToList();

EF語法:

var queryable = db.Queryable<Student>();
if (!string.IsNullOrEmpty(a)) {
    queryable = queryable.Where(it => it.Name == a);
}
if (!string.IsNullOrEmpty(b)) {
    queryable = queryable.Where(it => it.Name == b);
}
var list = queryable.ToList();

 是不是簡單很多呢?

4.輕量級

總大小隻有200多K,比EF的一個小插件都小,EF主體有5M

 

5.持續更新

 本來4.X預計3月份就可以開發完成的,因為換了新公司半年都是996工作制,我只有周日和晚上有時間開發,可以說我基本都沒有休息過。下半年工作不會這麼緊,我的時間會更充足一些。

 

功能詳解

SqlSugar 4.X  總共有九大核心功能,並且都設計為鏈式操作,鏈式操作有什麼好處?

第一鏈式操作可以減少方法的重載

第二鏈式操作可以讓代碼更加易讀,舉個例子一個方法有很多重載,你在寫的代碼就不清楚這些重載是做嘛的,需要F12到方法主體去看備註。

例如:第一種寫法就能清楚的知道 是否建創屬性,並且只創建Student這張表的文件,第二種方法雖然簡單不易讀

db.DbFirst.IsCreateAttribute().Where("Student").CreateClassFile("c:\\Demo\\5");
db.DbFirst.CreateClassFile(true,"Student","c:\\Demo\\5");

第三鏈式操更具有擴展性  例如有1234 我可以1和2一組,234一組 1和4一組,如果是重載的方式至少要有十個以上的重載後期將很難維護,功能越多後期易讀越差,也不靈活。

 

1.Queryable

查詢的核心對象,可以實現多表查詢,分組查詢,分頁,支持SqlFunc函數和拉姆達解析,除EF外也是對拉姆達解析支持最好的ORM之一

簡單查詢

查詢所有

var getAll = db.Queryable<Student>().ToList();

無鎖查詢

var getAllNoLock = db.Queryable<Student>().With(SqlWith.NoLock).ToList();

根據主鍵查詢

var getByPrimaryKey = db.Queryable<Student>().InSingle(2)

查詢單條沒有數據返回NULL, Single超過1條會報錯,First不會

var getSingleOrDefault = db.Queryable<Student>().Single();
var getFirstOrDefault = db.Queryable<Student>().First();

IN查詢

//Id In (1,2,3)
var in1 = db.Queryable<Student>().In(it=>it.Id,new int[] { 1, 2, 3 }).ToList();

//主鍵 In (1,2,3)
var in2 = db.Queryable<Student>().In(new int[] { 1, 2, 3 }).ToList();

//Id In (1,2)
int[] array = new int[] { 1, 2 };
var in3 = db.Queryable<Student>().Where(it=>array.Contains(it.Id)).ToList();

NOT IN查詢

var in3 = db.Queryable<Student>().Where(it=>!array.Contains(it.Id)).ToList();

多條件查詢

var getByWhere = db.Queryable<Student>().Where(it => it.Id == 1 || it.Name == "a").ToList();

使用函數 SqlFunc類

var getByFuns = db.Queryable<Student>().Where(it => SqlFunc.IsNullOrEmpty(it.Name)).ToList();

可以使用 SUM MAX MIN AVG查詢單個欄位

var sum = db.Queryable<Student>().Sum(it => it.Id);

Between 1 and 20

var between = db.Queryable<Student>().Where(it => SqlFunc.Between(it.Id, 1, 20)).ToList();

使用 AS 取新的表名

var getListByRename = db.Queryable<School>().AS("Student").ToList();

排序

var getAllOrder = db.Queryable<Student>()
.OrderBy(it => it.Id)//asc
.OrderBy(it => it.Name, OrderByType.Desc)//desc
.ToList()

是否存在這條記錄

var isAny = db.Queryable<Student>().Where(it => it.Id == -1).Any();
var isAny2 = db.Queryable<Student>().Any(it => it.Id == -1);

獲取同一天的記錄

var getTodayList = db.Queryable<Student>().Where(it => SqlFunc.DateIsSame(it.CreateTime, DateTime.Now)).ToList();

 

多表查詢

//LEFT JOIN 
var list = db.Queryable<Student, School>((st, sc) => new object[] {
JoinType.Left,st.SchoolId==sc.Id
})
.Where(st => st.Name == "jack").ToList();

//三表 LEFT JOIN
var list2 = db.Queryable<Student, School, Student>((st, sc, st2) => new object[] {
JoinType.Left,st.SchoolId==sc.Id,
JoinType.Left,st.SchoolId==st2.Id
})
.Where((st, sc, st2) => st2.Id == 1 || sc.Id == 1 || st.Id == 1).ToList();

//返回 List<ViewModelStudent>
var list3 = db.Queryable<Student, School>((st, sc) => new object[] {
JoinType.Left,st.SchoolId==sc.Id
}).Select((st, sc) => new ViewModelStudent { Name = st.Name, SchoolId = sc.Id }).ToList();

//join Order By (order by st.id desc,sc.id desc)
var list4 = db.Queryable<Student, School>((st, sc) => new object[] {
JoinType.Left,st.SchoolId==sc.Id
})
.OrderBy(st => st.Id, OrderByType.Desc)
.OrderBy((st, sc) => sc.Id, OrderByType.Desc)
.Select((st, sc) => new ViewModelStudent { Name = st.Name, SchoolId = sc.Id }).ToList();

 

多表查詢簡化,與JOIN的方式高低搭配,如果不需要LEFT JOIN可以簡寫成下麵的語句

var list5 = db.Queryable<Student, School>((st, sc) => st.SchoolId == sc.Id)
.Select((st,sc)=>new {st.Name,st.Id,schoolName=sc.Name}).ToList();

//三表查詢
var list6 = db.Queryable<Student, School,School>((st, sc,sc2) => st.SchoolId == sc.Id&&sc.Id==sc2.Id)
.Select((st, sc,sc2) => new { st.Name, st.Id, schoolName = sc.Name,schoolName2=sc2.Name }).ToList();
//三表查詢分頁 var list8 = db.Queryable<Student, School, School>((st, sc, sc2) => st.SchoolId == sc.Id && sc.Id == sc2.Id) .OrderBy(st=>st.Id) .Select((st, sc, sc2) => new { st.Name, st.Id, schoolName = sc.Name, schoolName2 = sc2.Name }).ToPageList(1, 2);

 

 

分組查詢

var group = db.Queryable<Student>().GroupBy(it => it.Id)
    .Having(it => SqlFunc.AggregateCount(it.Id) > 10)
    .Select(it => new { id = SqlFunc.AggregateCount(it.Id) }).ToList();

根據欄位分組取第一條,這個非常的好用

var list3 = db.Queryable<Student>()
.PartitionBy(it => new { it.Id, it.Name }).Take(1).ToList();

 

實體轉換支持2級模型

var s5 = db.Queryable<Student>().Select(it => new ViewModelStudent { Student = it, Name = it.Name }).ToList();
 
//實體結構  
public class ViewModelStudent {
  public Student Student{get;set;}
  pulic string Name{get;set;}
}

 

如果你是欄位串拼接愛好者你也可以這樣與拉姆達混用,或者純拼SQL

var join3 = db.Queryable("Student", "st")
        .AddJoinInfo("School", "sh", "sh.id=st.schoolid")
        .Where("st.id>@id")
        .AddParameters(new { id = 1 })
        .Select("st.*").ToList();

支持的原生函數 

.ToString

.Contains 

.Length

.ToLower

.ToUpper

.ToSubstring 

.Equals

.HasValue

.Replace

.EndsWith

.StartsWith

.Trim

 

支持的自定義函數


三元判段 ,相當於 it.id==1?1:2

SqlFunc.IIF(it.Id == 1, 1, 2)

判段是NULL或者空

SqlFunc.IsNullOrEmpty(object thisValue)

判段不是NULL並且不是空

SqlFunc.HasValue(object thisValue)

判段大於0並且不等於NULL

SqlFunc.HasNumber(object thisValue)

轉小寫

SqlFunc.ToLower(object thisValue)

轉大寫

SqlFunc.ToUpper(object thisValue)

去前後空格

SqlFunc.Trim(object thisValue)


模糊查詢 like %@p%

SqlFunc.Contains(string thisValue, string parameterValue)

也可以使用 .Where(it=>it.Name.Contains("a"));


In操作 thisValue={1,2,3} 生成的Sql就是 paramterValie in (1,2,3)

SqlFunc.ContainsArray(object[] thisValue, string parameterValue)

也可以使用 .Where(it=>Array.Contains(it.Id));
Not In 操作
.Where(it=>!Array.Contains(it.Id));


模糊查詢 like @p%

SqlFunc.StartsWith(object thisValue, string parameterValue

模糊查詢 like %@p

SqlFunc.EndsWith(object thisValue, string parameterValue)

等於

SqlFunc.Equals(object thisValue, object parameterValue)

是否是同一天

SqlFunc.DateIsSame(DateTime date1, DateTime date2)

是否是同一時間 (dataType 可以是年、月、天、小時、分鐘、秒和毫秒)

SqlFunc.DateIsSame(DateTime date1, DateTime date2, DateType dataType)

在當前時間加一定時間(dataType 可以是年、月、天、小時、分鐘、秒和毫秒)

SqlFunc.DateAdd(DateTime date, int addValue, DateType dataType)

在當前時間加N天

SqlFunc.DateAdd(DateTime date, int addValue)

獲取當前時間的年、月、天、小時、分鐘、秒或者毫秒

SqlFunc.DateValue(DateTime date, DateType dataType)

範圍判段

SqlFunc.Between(object value, object start, object end)

類型轉換

SqlFunc.ToInt32(object value) 
SqlFunc.ToInt64(object value)
SqlFunc.ToDate(object value) 
SqlFunc.ToString(object value) 
SqlFunc.ToDecimal(object value) 
SqlFunc.ToGuid(object value) 
SqlFunc.ToDouble(object value) 
SqlFunc.ToBool(object value)

截取字元串

SqlFunc.Substring(object value, int index, int length)

替換字元串

SqlFunc.Replace(object value, string oldChar, string newChar)

獲取字元串長度

SqlFunc.Length(object value) { throw new NotImplementedException(); }

聚合函數

SqlFunc.AggregateSum<TResult>(TResult thisValue) 
SqlFunc.AggregateAvg<TResult>(TResult thisValue)
SqlFunc.AggregateMin(TResult thisValue) 
SqlFunc.AggregateMax<TResult>(TResult thisValue) 
SqlFunc.AggregateCount<TResult>(TResult thisValue)

如果還有不支持的可以寫字元串

db.Queryable<Student>().Where("xxx(xx)")

 

2.Updateable

updateable主要功能有批量更新、單條更新、指定更新列、排除更新列、根據拉姆達更新、根據實體更新等操作

根據實體更新(主鍵要有值,主鍵是更新條件)

var t1 = db.Updateable(updateObj).ExecuteCommand();

只更新實體裡面的Name列(主鍵要有值,主鍵是更新條件)

var t3 = db.Updateable(updateObj).UpdateColumns(it => new { it.Name }).ExecuteCommand();

更新 Name和 TestId 以外的所有列 (主鍵要有值,主鍵是更新條件)

var t4 = db.Updateable(updateObj)
.IgnoreColumns(it => new { it.Name, it.TestId }).ExecuteCommand();

更新NAME

var t5 = db.Updateable(updateObj)
.IgnoreColumns(it => it=="name" ).With(SqlWith.UpdLock).ExecuteCommand();

使用鎖

var t6 = db.Updateable(updateObj).With(SqlWith.UpdLock).ExecuteCommand();

批量更新(主鍵要有值,主鍵是更新條件)

List<Students> list=GetList();
var t7 = db.Updateable(list).ExecuteCommand();

實體更新,並且給指定列重新賦值

var t8 = db.Updateable(updateObj)
.ReSetValue(it => it.Name == (it.Name + 1)).ExecuteCommand();

更新實體,更新條件是根據表達示

var t9 = db.Updateable(updateObj).Where(it => it.Id == 1).ExecuteCommand();

根據表達式中的列更新 ,指定列並賦值的更新,比較常用

var t10 = db.Updateable<Student>()
.UpdateColumns(it => new Student() { Name = "a", CreateTime = DateTime.Now })
.Where(it => it.Id == 11).ExecuteCommand();

 

別名錶

db.Updateable<School>().AS("Student")
.UpdateColumns(it => new School() { Name = "jack" })
.Where(it => it.Id == 1).ExecuteCommand();
//Update Student set Name='jack' Where Id=1

是NULL的列不更新
db.Updateable(updateObj).Where(true).ExecuteCommand();

 

3.Insertable

Insertable主要功能有 批量插入、單條插入、指定插入列、排除插入列等功能

插入並返回受影響行數用ExecuteCommand

var t2 = db.Insertable(insertObj).ExecuteCommand();

插入並返回自增列用ExecuteReutrnIdentity

var t3 = db.Insertable(insertObj).ExecuteReutrnIdentity();

只插入列 Name和SchoolId

var t4 = db.Insertable(insertObj).InsertColumns(it => new { it.Name, it.SchoolId }).ExecuteReutrnIdentity();

不插入列 Name和TestId

var t5 = db.Insertable(insertObj).IgnoreColumns(it => new { it.Name, it.TestId }).ExecuteReutrnIdentity();

根據條件指定不插入列

var t6 = db.Insertable(insertObj).IgnoreColumns(it => it == "Name" || it == "TestId").ExecuteReutrnIdentity();

使用鎖

var t8 = db.Insertable(insertObj).With(SqlWith.UpdLock).ExecuteCommand();

可以設置NULL列不插入和是否強制插入自增列

var t9 = db.Insertable(insertObj2)
.Where(true/* Is no insert null */, true/*off identity*/)
.ExecuteCommand();

批量插入

var insertObjs = new List<Student>();
var s9 = db.Insertable(insertObjs.ToArray()).ExecuteCommand();

 

Deleteable

根據主鍵刪除、單條刪除、條件刪除、表達式刪除等功能

根據實體刪除(實體內主鍵一定要有值)

var t0 = db.Deleteable<Student>().Where(new Student() { Id = 1 }).ExecuteCommand();

根據實體集刪除

var t1 = db.Deleteable<Student>().Where(new List<Student>() { new Student() { Id = 1 } }).ExecuteCommand();

使用鎖

var t2 = db.Deleteable<Student>().With(SqlWith.RowLock).ExecuteCommand();

根據主鍵刪除

var t3 = db.Deleteable<Student>().In(1).ExecuteCommand();

根據主鍵批量刪除

var t4 = db.Deleteable<Student>().In(new int[] { 1, 2 }).ExecuteCommand();

根據表達式刪除

var t5 = db.Deleteable<Student>().Where(it => it.Id == 1).ExecuteCommand();

 

其它功能的一些簡介

因為功能太多九大功能只講了4大功能的用法,其它功能我就簡單描述一下

DbFirst:用於創建實體、支持模型自定義、可以生成全部表的實體、也可以指定表和支持生成屬性和預設值

CodeFirst:支持通過類生成實體、主鍵、自增列、支持表的備份和欄位名稱的修改

Ado.Net: 支持SqlQuery<T> 一系列 原生SQL操作 支持事務、存儲過程輸出參數等功能

DbMaintenance:資料庫的維護操作 支持表備份、庫備份、添加表、添加列、獲取表信息 、根據表獲取主鍵等相關資料庫層面的操作

EntityProvider:獲取實體類的相關信息

 

另外支持了複雜模型的用法:

  var students = db.Queryable<CMStudent>().ToList();
  if (students != null)
  {
       foreach (var item in students)
       {
            Console.WriteLine(item.SchoolName);
 
            Console.WriteLine(item.SchoolSingle.Name);
             
            Console.WriteLine(item.SchoolList.Count);
    }
  }

 

源碼下載:

https://github.com/sunkaixuan/SqlSugar

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 定義:保護共用資源,使得資源在一個時刻只有一個進程(線程)擁有 原理:信號量值為正時說明空閑,若為0或負值則說明被占用 分類:內核信號量與用戶信號量,用戶信號量分為POXIS信號量和SYSTEMV信號量,POXIS信號量分為有名信號量和無名信號量 內核信號量: #include<asm/semaph ...
  • du -sh 查看當前文件夾下文件與文件夾大小; df -hl 查看磁碟空間大小; ...
  • 最近重裝了系統,於是便重新配置了一下終端,使其更符合用戶習慣。 效果如下: 擁有語法高亮,命令行tab補全,自動提示符,顯示Git倉庫狀態等功能。 安裝 首先我們下載的 iTem2 這個軟體,比Mac自帶的終端更加強大。直接官網 http://iterm2.com/ 下載並安裝即可。 配置 將iTe ...
  • yum groups install -y "GNOME Desktop" "Graphical Administration Tools" ...
  • 在實際的系統開發中,我們往往需要一些簡單的的案例代碼,基於此目的我把Winform開發框架中各種閃光點和不錯的功能,有些是我們對功能模塊的簡單封裝,而有些則是引入了一些應用廣泛的開源組件進行集成使用,因此把它們做了一個Demo進行展示,以方便我們隨時瞭解和參考,並能夠快速應用相應的場景到具體的項目中... ...
  • 軟體環境: Win7 x64 SP1 SQL Server 2008r2 Visual Studio 2017 Professional 目標:取出示例資料庫 ReportServer 的表 Roles 中的所有記錄並顯示。 步驟: 一、添加軟體包 使用NuGet添加以下軟體包: ServiceSt ...
  • 一、泛型 假設我要寫個公用的輸出傳入參數的方法(不用泛型),因為萬物皆對象的理由,我先定義一個方法show(object obj),如下麵所示: 執行這個方法 如果傳入的是值類型,值類型轉換為引用類型,我們知道會發生裝箱,這是對性能的損害,想想如果是個集合,就得多次執行裝箱、拆箱操作。如ArrayL ...
  • .net core 填坑記之二目錄問題(獲取當前目錄、創建目錄) ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...