又是寫ORM的博客,但是寫其它的類庫,我不會啊,只有這個我能寫一寫,希望大家輕噴 最近修改內容 以前只支持.NET Framework,現在修改為支持.NET Framework、.NET Standard、.NET Core多目標平臺 以前工程依賴了具體的資料庫操作類庫,不方便實現支持多目標平臺, ...
又是寫ORM的博客,但是寫其它的類庫,我不會啊,只有這個我能寫一寫,希望大家輕噴
最近修改內容
以前只支持.NET Framework,現在修改為支持.NET Framework、.NET Standard、.NET Core多目標平臺
以前工程依賴了具體的資料庫操作類庫,不方便實現支持多目標平臺,為此,修改了架構,把Provider移到了工程外
這樣改造之後,竟然可以支持任意關係資料庫,需要編寫的Provider,需要實現的功能很少,除了創建分頁SQL,就沒什麼了,lambda可以不支持。
寫完之後進行性能測試,對比EF、Dapper、FreeSql、SqlSugar,發現迴圈更新和查詢,性能比較差,為此,我看了Dapper、FreeSql、SqlSugar,實體類賦值相關的源碼,發現SqlSugar用的是Emit,Dapper用的是Emit和表達式樹,而FreeSql用的是表達式樹,而我用的是反射,性能自然差一些,不過反射賦值代碼很簡單。經過學習,我用Emit實現了相同的性能,但做更多測試的時候,發現了BUG,於是我去看它們的源碼,發現代碼量都不小,FreeSql的表達式樹,居然有2000多行代碼,SqlSugar也不簡單,麻煩的主要是數據類型處理,居然還為SQLite做了單獨處理。於是我放棄了,使用反射,性能也只能這樣了。
突然想到,我可以把底層用的ADO.NET換成Dapper,一來性能好,二來大家更信任Dapper,這樣的話,這個DBHelper實際做的工作就更少了,插入、更新則是把實體類翻譯成SQL交給Dapper執行,查詢則是把SQL直接交給Dapper執行,當然,分頁查詢Dapper本身是沒有的,我想可能是因為分頁SQL,不同的資料庫寫法差異很大,所以Dapper把它交給擴展去做了。看到NuGet上眾多的Dapper擴展,我突然感覺,Dapper其實不是一個ORM,它是一個基礎設施,就像JdbcTemplate一樣。
說乾就乾,也就花了一天,把底層換成了Dapper,查詢性能和FreeSql、SqlSugar一樣了,分頁查詢慢一點,因為我在分頁查詢里,查了總數,看來這個方法後面需要再優化一下,可是更新還是慢,因為我在更新里,又查了一次數據,然後比對,只更新變化的欄位。繼續優化,參照FreeSql的Attach,實現了一個AttachOld方法,用到AutoMapper以保證性能,用於把更新前的舊數據存一下,這樣修改之後,更新的性能也和FreeSql、SqlSugar一樣了,至此,性能問題算是基本解決了。
收穫
-
學會了NuGet打包發佈
最近一共發了4個NuGet包
https://www.nuget.org/profiles/s0611163 -
學會瞭如何開發支持多目標平臺的庫
感想
平時工作漸漸以Java為主了,工作中寫C#的機會越來越少。Java開源項目太多,加上自己初學,也沒有水平寫類庫,寫Java自己只是個調包俠,開源框架源碼也看不懂。通過寫C#、看C#的開源項目源碼,可以練練技術。工作多年,以前從未看過別人寫的源碼,最近,因為想寫好自己的類庫,所以看了一點NLog、以及各ORM的源碼,學了一點東西。還是很喜歡.NET的,最近把自己寫的LogUtil放到Linux系統下跑了跑,算是初步學會瞭如何把.NET程式跑在Linux系統上。
我看好.NET,期待.NET 8,但願以後有機會在工作中使用。
NuGet地址
-
非Dapper版
可以支持更多的資料庫,Provider需要自己寫,不過代碼量很小
https://www.nuget.org/packages/sux.DBHelper -
Dapper版
.NET Framework 4.6.1及以上
https://www.nuget.org/packages/Dapper.DBHelper
源碼地址
-
Gitee地址
-
GitHub地址
-
.NET5 .NET6測試源碼