開源一個基於dotnet standard的輕量級的ORM框架-Light.Data
還在dotnet framework 2.0的時代,當時還沒有EF,而NHibernate之類的又太複雜,並且自己也有一些特殊需求,如查詢結果直接入表、水平分表和新增資料預設值等,就試著折騰個輕量點ORM框架,就慢慢有了這個Light.Data,也一直在公司和個人的專案使用,後來陸陸續續也支援了跨資料庫並在mono中使用。到了dotnet core來臨,也嘗試移植,1.0的時候由於類庫不完善,效果不理想。2.0的基本完善了,由於個人嚴重的強迫症和拖延症,一直在折騰細節、寫單元測試和磨文件,磨到差不多3.0快來了。。。。
不說廢話了,Light.Data
是一個輕量級的基於dotnet standard 2.0
Attribute
或者配置檔案進行配置與資料表的對應關係. 使用核心類DataContext
對資料表進行CURD
的操作.
PM> Install-Package Light.Data
支援資料庫
資料庫 | 說明 |
---|---|
SqlServer | 安裝Light.Data.Mssql 類庫, 支援SqlServer 2008或以上 |
Mysql | 安裝Light.Data.Mysql 類庫, 支援Mysql 5.5或以上 |
Postgre | 安裝Light.Data.Postgre 類庫, 支援Postgre9.3或以上 |
-
使用文件: https://aquilahkj.github.io/Light.Data.Site/#/zh-cn/
-
Github: https://github.com/aquilahkj/Light.Data2
連線配置
{ "lightData": { "connections": [ { "name": "mssql_db", "connectionString": "...", "providerName": "Light.Data.Mssql.MssqlProvider, Light.Data.Mssql" }, { "name": "mysq_db", "connectionString": "...", "providerName": "Light.Data.Mysql.MysqlProvider, Light.Data.Mysql" } ] } }
使用方式
// 直接使用 DataContext context = new DataContext("mssql"); // 建立子類 public class MyDataContext : DataContext { public MyDataContext() : base("mssql") { } } // 建立配置子類 public class MyDataContext : DataContext { public MyDataContext(DataContextOptions<MyDataContext> options) : base(options) { } } // 直接配置連線字串和引數 (IServiceCollection) service.AddDataContext<MyDataContext>(builder => { builder.UseMssql(connectionString); builder.SetTimeout(2000); builder.SetVersion("11.0"); }, ServiceLifetime.Transient); // 預設配置檔案配置 (IServiceCollection) service.AddDataContext<MyDataContext>(DataContextConfiguration.Global, config => { config.ConfigName = "mssql"; }, ServiceLifetime.Transient);
物件對映
1 [DataTable("Te_User", IsEntityTable = true)] 2 public class TeUser 3 { 4 /// <summary> 5 /// Id 6 /// </summary> 7 /// <value></value> 8 [DataField("Id", IsIdentity = true, IsPrimaryKey = true)] 9 public int Id 10 { 11 get; 12 set; 13 } 14 15 /// <summary> 16 /// Account 17 /// </summary> 18 /// <value></value> 19 [DataField("Account")] 20 public string Account 21 { 22 get; 23 set; 24 } 25 26 /// <summary> 27 /// Telephone 28 /// </summary> 29 /// <value></value> 30 [DataField("Telephone", IsNullable = true)] 31 public string Telephone 32 { 33 get; 34 set; 35 } 36 .... 37 }
基本操作
- 基本CURD
- 批量CUD
- 支援事務處理
- 支援資料欄位預設值和自動時間戳
- 支援資料欄位讀寫控制
- 查詢結果指定類或匿名類輸出
- 查詢直接插入資料表
1 var context = new DataContext(); 2 // 查詢單個數據 3 var item = context.Query<TeUser>().Where(x => x.Id == 10).First(); 4 // 查詢集合資料 5 var list = context.Query<TeUser>().Where(x => x.Id > 10).ToList(); 6 // 新增資料 7 var user = new TeUser() { 8 Account = "foo", 9 Password = "bar" 10 }; 11 context.Insert(user); 12 // 修改資料 13 user.Password = "bar1"; 14 context.Update(user); 15 // 刪除資料 16 context.Delete(user);
資料彙總
- 單列資料直接彙總
- 多列資料分組彙總
- 格式化分組欄位
- 彙總資料直接插入資料表
1 // 普通匯總 2 var list = context.Query<TeUser> () 3 .Where (x => x.Id >= 5) 4 .GroupBy (x => new LevelIdAgg () { 5 LevelId = x.LevelId, 6 Data = Function.Count () 7 }) 8 .ToList (); 9 10 // 日期格式化統計 11 var list = context.Query<TeUser> () 12 .GroupBy (x => new RegDateFormatAgg () { 13 RegDateFormat = x.RegTime.ToString("yyyy-MM-dd"), 14 Data = Function.Count () 15 }) 16 .ToList ();
連表查詢
- 多表連線, 支援內連線, 左連線和右連線
- 支援查詢結果和彙總資料連線
- 連線查詢結果指定類或匿名類輸出
- 連線查詢結果直接插入資料表
1 // 內連線 2 var join = context.Query<TeUser> () 3 .Join<TeUserExtend>((x,y) => x.Id == y.Id); 4 5 // 統計結果連線實體表 6 var join = context.Query<TeMainTable>() 7 .GroupBy(x => new { 8 MId = x.MId, 9 Count = Function.Count(), 10 }) 11 .Join<TeSubTable>((x, y) => x.MId == y.Id);
執行SQL語句
- 直接使用SQL語句和儲存過程
- 支援物件引數
- 查詢結果指定類或匿名類輸出
- 儲存過程支援output引數
1 // 普通引數 2 var sql = "update Te_User set NickName=@P2 where Id=@P1"; 3 var ps = new DataParameter[2]; 4 ps[0] = new DataParameter("P1", 5); 5 ps[1] = new DataParameter("P2", "abc"); 6 var executor = context.CreateSqlStringExecutor(sql, ps); 7 var ret = executor.ExecuteNonQuery(); 8 9 // 物件引數 10 var sql = "update Te_User set NickName={nickname} where Id={id}"; 11 var executor = context.CreateSqlStringExecutor(sql, new { nickname = "abc", id = 5 }); 12 var ret = executor.ExecuteNonQuery();
單元測試
專案使用xUnit做單元測試,測試程式碼地址:https://github.com/aquilahkj/Light.Data2/tree/master/test
每種資料庫均有300多組1000多用例的測試,覆蓋大部分程式碼。
效能測試
目前只跟EF Core在同一電腦的Docker上的Sql Server 2017 for linux中做簡單的增刪改查效能對比測試,程式碼地址 https://github.com/aquilahkj/OrmTest
1000次的增刪改和單條資料查詢
共5輪,每輪1000條的增刪改和1000條資料查詢
EF的測試結果
Light.Data測試結果
從對比看,查詢效能兩者差不多,新增效能Light.Data稍微佔優,批量更新也稍微佔優。
另外值得一提的是Postgre,批量增刪改效能比Sql Server快2,3倍,看來以後也要好好研究一下。
以上均是非嚴謹測試,僅供參考。
最後
本文只是簡單的介紹,具體使用方法可以檢視文件和參考測試用例,如有需要會寫具體使用的文章。
Light.Data這個專案這麼多年來個人一直維護,也在不斷優化,不斷成長,但一直養在深閨,好不容易折騰開源也是希望能共享出去,給有需要的朋友多個選擇,同時也是給自己這麼多年碼農的見證。
雖然現在ORM的框架非常非常多,也不是什麼熱門新鮮事物,但總歸是個基礎的東西。
如果有朋友喜歡,不妨試試,可以的話,給個Star,十分歡迎意見或建議 :D