LambdaToSql(輕量級ORM) 入門篇 開源專案
為什麼開發(背景)
最開始使用的是 sqlDbHelper,有微軟的,有自己寫的。
後來開始使用比較成熟的框架開發,使用過一段時間的Hibernate,後期主要使用 Entity FrameWork。
發現表越多 業務越複雜後,越不好控制專案,所以慢慢的自己根據業務寫了一個小工具,也就是本文說的 LambdaToSql。
最開始的功能 主要是準備替代DbHelper的,慢慢的把對映關係加上了,再後來重構了幾次,就慢慢的代替了EF的功能。
現在有幾個成熟的專案在使用,軟體也會一直維護下去,現在基本都是核心功能,暫時沒往大而全去做。
ORM介紹
鏈式查詢、鏈式更新、鏈式刪除、鏈式插入、複雜模型的查詢、ADO.NET。
支援資料庫:現在只支援 MS Sql Server,其他資料庫暫時未做支援處理,裡面預留了對其它資料庫支援的介面,但未實現程式碼邏輯。
資料庫預留介面:Oracle、Mysql、Access。
功能: 基本CURD(新增,修改,讀取,刪除)功能,批次修改,DbFirst,表快取。
全部使用Lambda語法,開發簡潔,程式碼乾淨,後期好維護。
有點2:效能高,基本接近於原生ADO,語法簡單,功能強大,持續更新維護。
其實LambdaToSql不能算是一個ORM,主要功能其實還應該算是Dapper替代產品,主要是把對映物件透過Lambda形式轉換成sql語句,透過Ado做 CURD操作。
缺點1:不支援多表查詢,Join效能還是比較低,但後期還是會支援join查詢。
缺點2:暫時不支援外部自定義函式和繼承覆蓋重寫,後期慢慢也會開放出來。
如果有想自定義的,可以直接使用原始碼改動哦。
效能測試
測試環境: 硬碟:三星 SSD 850 EVO; CPU:i7-7700K
新增100w條資料 耗時大概250s內
查詢100w條資料並生成實體.Tolist(),大概3s
100w資料,每頁50條,取中間資料,大概100ms內
插入/更新/查詢 單條資料 大概20ms內
刪除 單條大概 20ms內
開源地址
碼雲gitee:
Demo示例:
如何安裝
原始碼方式:可以直接在gitee下載,在專案中直接使用
透過Nuget下載引用: 開啟Nuget 搜尋:LambdaToSql 就可以了
Nuget命令方式:
Install-Package LambdaToSql
Config配置,連結資料庫
初始化LambdaToSql 物件
//預設方式LambdaToSql.SqlClient DB = new LambdaToSql.SqlClient();
//自定義連結字串名稱var DB = new LambdaToSql.SqlClient(new LambdaToSql.EntityModel.DbContext() { ConnectionStringName = "ConnectionString1", SqlType = LambdaToSql.EntityModel.SqlType.MsSqlServer });
初次使用,如何生成實體類:DbFirst
//生成實體儲存路徑var saveFolder = "d:\class\";//生成全部實體DB.DbFirst.Create(saveFolder);//生成指定表實體物件DB.DbFirst.CreateByTable(saveFolder, new List() { "Table_ID", "Table_Guid" });
查詢
////// 查詢/// public void Query() { //查詢全部 var list = DB.QueryTable().ToList(); //Find主鍵查詢,支援Guid 和int 自增主鍵 var entity = DB.QueryTable ().Find(200); //In查詢 var arr = new int?[] { 100, 101, 102, 103 }.ToList(); var list1 = DB.QueryTable (ex => arr.Contains(ex.ID)).ToList(); //Not In 查詢 var list2 = DB.QueryTable (ex => ex.ID.ExNotIn(arr)).ToList();//有問題 var list2_1 = DB.QueryTable (ex => arr.NotContains(ex.ID)).ToList();//有問題 // Like 查詢 var list3 = DB.QueryTable ().Where(ex => ex.LoginName.Contains("15")).ToList();//(LoginName like '%15%') var list4 = DB.QueryTable ().Where(ex => ex.LoginName.NotContains("15")).ToList();//(LoginName not like '%15%') //有問題 var list5 = DB.QueryTable ().Where(ex => ex.LoginName.StartsWith("15")).ToList();//(LoginName like '15%') var list6 = DB.QueryTable ().Where(ex => ex.LoginName.EndsWith("15")).ToList();//(LoginName like '%15') //排序 var list7 = DB.QueryTable ().OrderBy(ex => ex.CreateTime).OrderByDescending(ex => ex.LoginName).ToList(); //分組 var list8 = DB.QueryTable ().GroupBy(ex => new { ex.LoginName, ex.UserName }).ToList(); //只取特定欄位 var list9 = DB.QueryTable ().Select(ex => new { ex.LoginName, ex.UserName }).ToList(); //top N var list10 = DB.QueryTable ().Take(10).ToList(); //第幾頁 var list11 = DB.QueryTable ().Skip(2).Take(10).ToList(); //取第一條資料 var list12 = DB.QueryTable ().First(); var list13 = DB.QueryTable ().FirstOrDefault(); //分頁 2005,2008使用row_number分頁,2012以上使用offset分頁形式 int total = 0; var list14 = DB.QueryTable ().Skip(15).Take(30).ToPageList(ref total); //分組 select 比原始去重效能要高一些 DB.QueryTable ().GroupBy(ex => new { ex.UserName, ex.LoginName }) .Select(ex => new { ex.UserName, ex.LoginName }) .ToList(); //判斷滿足條件的資料是否存在 var flag = DB.QueryTable ().Any(); //判斷滿足條件的資料是否存在 var flag1 = DB.QueryTable (ex => ex.ID == 2000).Any(); }
函式處理
////// 函式處理/// private void Fun() { //求和 var num1 = DB.QueryTable().Sum(ex => ex.IsDelete); //最小值 var num2 = DB.QueryTable ().Min(ex => ex.IsDelete); //最大值 var num3 = DB.QueryTable ().Max(ex => ex.IsDelete); //平均值 var num4 = DB.QueryTable ().Avg(ex => ex.IsDelete); //總數 var num5 = DB.QueryTable ().Count(); }
新增
////// 新增資料/// public void Inser() { //新增單個實體物件 var entity = new EntityModel.Table_ID() { LoginName = "登入使用者:", UserName = "使用者名稱:", PassWord = "密碼-", Gender = "男", IsDelete = 0, Mobile = "15804066511", Remark = "備註", Address = "地址:", CreateTime = DateTime.Now }; var ret = DB.InsertTble(entity).ExecuteNonQuery();//返回主鍵值 //只新增某幾列 var i = DB.InsertTble(entity).InsertColumns(ex => new { ex.LoginName, ex.UserName, ex.Remark }).ExecuteNonQuery(); //忽略某些列 var i1 = DB.InsertTble(entity).IgnoreColumns(ex => new { ex.Mobile, ex.PassWord }).ExecuteNonQuery(); }
修改
NULL列不做更新處理
暫時只支援uniqueidentifier和int自增型別單主鍵
////// 更新資料/// public void Update() { //更新單個實體物件 var entity = DB.QueryTable(ex => ex.ID == 200).FirstOrDefault(); entity.PassWord = "12345"; entity.LoginName = "LambdaToSql"; entity.UserName = "LambdaToSql1"; var i = DB.UpdateTble(entity).ExecuteNonQuery(); //更新特定欄位,不指定不更新 var i1 = DB.UpdateTble(entity).UpdateColumns(ex => new { ex.PassWord }).ExecuteNonQuery(); //忽略特定欄位,其他欄位都更新 var i2 = DB.UpdateTble(entity).IgnoreColumns(ex => new { ex.UserName, ex.PassWord }).ExecuteNonQuery(); //條件更新 不需要取出實體物件 直接資料庫更新 var i3 = DB.UpdateTble(new EntityModel.Table_ID() { PassWord = "123456", LoginName = "12" }).Where(ex => ex.ID == 101).ExecuteNonQuery(true); }
刪除
////// 刪除/// public void Delete() { //刪除單個實體,透過主鍵刪除 var entity = DB.QueryTable(ex => ex.ID == 200).FirstOrDefault(); var i = DB.DeleteTble (entity).ExecuteNonQuery(); //條件刪除 支援查詢裡面的所有條件寫法 var i1 = DB.DeleteTble (ex => ex.ID == 201).ExecuteNonQuery(); }
事務
事務使用注意:
事務只能在同一個SqlClient物件有效;事務只能在同一個SqlClient物件有效;事務只能在同一個SqlClient物件有效;重要的事說三遍
跨SqlClient物件請用分散式事務(暫時內建不支援,後續版本會支援分散式事務)
////// 事務/// public void Tran() { var sqlClient = new LambdaToSql.SqlClient(); try { sqlClient.BeginTran();//開啟事務 //新增單個實體物件 var entity = new EntityModel.Table_ID() { LoginName = "登入使用者:", UserName = "使用者名稱:", PassWord = "密碼-", IsDelete = 0, CreateTime = DateTime.Now }; var entity1 = new EntityModel.Table_ID() { LoginName = "登入使用者:", UserName = "在破敗中崛起,在寂滅中復甦。滄海成塵,雷電枯竭,那一縷幽霧又一次臨近大地,世間的枷鎖被開啟了,一個全新的世界就此揭開神秘的一角:", PassWord = "密碼-", IsDelete = 0, CreateTime = DateTime.Now }; var entity2 = new EntityModel.Table_ID() { LoginName = "登入使用者:", UserName = "使用者名稱:", PassWord = "密碼-", IsDelete = 0, CreateTime = DateTime.Now }; sqlClient.InsertTble(entity).ExecuteNonQuery(); sqlClient.InsertTble(entity1).ExecuteNonQuery();//錯誤 UserName太長=>回滾 sqlClient.InsertTble(entity2).ExecuteNonQuery(); sqlClient.CommitTran();//提交事務 } catch (Exception ex) { sqlClient.RollbackTran();//回滾事務 } }
ADO
////// Ado/// public void Ado() { var sql = "select top(10) * from table_id"; var sdr = DB.Ado.ExecuteReader(sql); var list = new List(); while (sdr.Read()) { list.Add(sdr[0].ToString()); } sdr.Close(); var Dt = DB.Ado.ExecuteTable(sql); var ls1 = DB.Ado.ExecuteScalar(sql); var ls = DB.Ado.ExecuteScalars(sql); var i = DB.Ado.ExecuteNonQuery("update top (10) table_id set imgurl = 'img1'"); }
後續計劃
繼續維護程式碼和升級新功能
把類庫UML圖釋出出來
把類介面和實現文件 整理好 釋出出來
會在開源一個關於WebApi的整體框架結構
最近另一個開源專案: 這是個通用類庫專案,把平時常用的整理了下,自己也一直在使用此類庫
結尾
希望大家多多提bug
希望大家多多提意見
最後,感謝SqlSugar專案作者開源
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3407/viewspace-2804520/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 輕量級orm框架——gzero指南ORM框架
- 輕量級ORM框架——第一篇:Dapper快速學習ORM框架APP
- 專案輕量級部署神器:Fabric
- 開源一個基於dotnet standard的輕量級的ORM框架-Light.DataORM框架
- 用go設計開發一個自己的輕量級登入庫/框架吧(專案維護篇)Go框架
- 手寫ORM入門篇(一)ORM
- 華為開源專案ServiceComb快速入門
- Laravel + Vue.js 前後端分離之新手入門級的開源專案(最終篇)LaravelVue.js後端
- 大資料入門指南(GitHub開源專案)大資料Github
- PetaPoco .net 輕量級orm簡單實用教程ORM
- python輕量級orm框架 peewee常用功能速查PythonORM框架
- Midori:輕量級開源 Web 瀏覽器Web瀏覽器
- Spring 5| 輕量級的開源JavaEE框架SpringJava框架
- 推薦一個Star超過2K的.Net輕量級的CMS開源專案
- .Net orm 開源專案 FreeSql 2.0.0(滿意的答卷)ORMSQL
- 一個輕量級,0配置orm框架 sharkchili-feifeiORM框架
- spellsql 高效能sql拼接器和輕量級ormSQLORM
- ORM入門ORM
- C# 輕量級 ORM 框架 NPoco 的簡單應用C#ORM框架
- 不想寫sql?試試這款輕量級JAVA ORM框架!SQLJavaORM框架
- 一款針對EF Core輕量級分表分庫、讀寫分離的開源專案
- webpack入門級 - 從0開始搭建單頁專案配置Web
- Github上最受歡迎的Python輕量級框架Flask入門GithubPython框架Flask
- 【原創】基於.NET的輕量級高效能 ORM - XFrameworkORMFramework
- Python 入門 — 資源篇Python
- 開源輕量級 IM 框架 MobileIMSDK v6.1.2 釋出!框架
- 輕量級專案管理工具——Excel 甘特圖模板專案管理Excel
- python3 專案開發-中級篇Python
- Python:輕量級 ORM 框架 peewee 用法詳解之——增刪改查PythonORM框架
- Python:輕量級 ORM 框架 peewee 用法詳解(二)——增刪改查PythonORM框架
- 宜信開源專注業務邏輯的輕量級服務框架nextsystem4框架
- Oracle釋出開源的輕量級 Java 微服務框架 HelidonOracleJava微服務框架
- 阿里開源!輕量級深度學習端側推理引擎 MNN阿里深度學習
- 使用 TypeScript + React + Redux 進行專案開發(入門篇,附原始碼)TypeScriptReactRedux原始碼
- 測開入門篇《環境管理、編碼規範、專案結構》
- 開源輕量級 PHP 資料庫 ORM 框架 ycdb (高階) : 構建穩定的資料庫 / 快取連線池PHP資料庫ORM框架快取
- 用go設計開發一個自己的輕量級登入庫/框架吧(業務篇)Go框架
- 輕量ORM-SqlRepoEx (十一)擴充套件ORMSQL套件