很多人都不太認可以第三方ORM,因為考慮的點不夠全面,沒有使用者群體大的ORM有保證,這點是不可否認確是事實。
但是往往使用者群體大的ORM又有不足之處,就拿使用者群體最多的兩個ORM來說一下吧
1、EF
EF效能夠用,但是總體還是和輕量級ORM有一定差距,如果沒有差距就沒有Dapper什麼事兒了。
2、Dapper
效能不錯,相容也好但是就是語法太少,基本都要手寫SQL,或自已擴充套件,自己擴充套件考慮的點可能連第三方ORM都不如,只能夠自已需求使用,發現問題自已來改,沒發現問題也挺安逸。
我的ORM之旅
1、感謝大家的幫助
第一 要感謝上海藍燈資料科技股份有限公司給我構架師一職讓.NET部門都使用我的技術框架
第二 百籤軟體的老總的大力支援除了自已員工使用外還幫我喧傳
第三 群( 225982985)裡的朋友向我提了很多保貴的問題和改進的建議。
第四 chloe.ORM的作者,兩個人都為了ORM基情四射
2、談一談開發SqlSugarORM框架中遇到的一些坑
而這些坑我發現部落格園的一些其它ORM也普遍存在,所以我將這些問題一一的分享,也希望更多人能夠指出SqlSugar的不足之處。
(1)、避免Sql執時計劃失效
Sql執行計劃是什麼,簡單的說就是讓Sql伺服器更明確的知道你要做什麼,將你的操作步驟存起來,下一次遇到同樣的SQL便使用同樣的操作步驟 ,大大降低SQL操作的步驟,提高效能,引起的效能差距可能是成倍的 。
引數化比拼SQL效能高的原因,也就是因為呼叫了系統儲存過程 sp_executesql 將Sql執行計劃的優勢發揮了出來
如下圖 name的長度為11,因為sqlparameter沒有指定Size 所以nvarchar的數字是動態的,所以會導致Sql執行計劃無效,一般的效能測試很難測出來,這種情況將會打亂Sql執行計劃,當引數越多,引數的長度越大效能差距越明顯。
而固定長度的測試根本發現不了。
解決方案:
將SqlParameter size<4000
全部設為4000,EF和Dapper在這點上就做的非常的棒
例如出現 id<1&&id>0處理兩個相同的名字引數時 id<@id and id>@id+隨機數
只要加了隨機數就無法進執行計劃了
解決方案:
自增數 id<@id and id>@id1
2、資料類形轉換成實體的處理
這一點就Dapper做的最好,EF也不錯給出了很明確的錯誤資訊。
為什麼說Dapper做的最好呢,因為Dapper能把資料的int轉換成實體類中的string。資料庫是string轉換成int時就給出了非常明確的錯誤資訊。
目前第三方ORM都沒在這方面做很好的處理
解決方案:
需要做很細的型別判段,我的做法是在Emit生成Dynamicbuilder之前處理,用資料庫型別和實體類體做對比,將異常提前丟擲,沒有異常EMIT物件將存進快取,預熱後不會在執行。
3、效能的突破
就單純拿Emit將DataReader轉成List<T>來說,第三方的ORM基本上都做到了比Dapper快或者說平分秋色。
預熱後一次查詢100萬條資料這是最好的測試方式,但要注意一點 如果走的是 DataReader的索引器 那就會有效能損耗
GetValue和索引器都是Object型別執行轉換後將會產生 拆箱(將OBJECT轉成了值型別),SqlSugar能在這個方面得到改進,多虧Chloe.ORM作者幫我發現了這個問題
4、拉姆達解析效能
如何測試自已拉姆達解析成SQL過程花時間多長呢,
測試方法:每執行一次只查詢一條資料,WHERE條件多設一點。執行次數10000以上。
解決方案:在解析過程中千萬不能用 Expression.Lambda(exp).Compile().DynamicInvoke();
用了這種寫法將會帶來十倍的效能之差,按上面的測試方式很容易測出效能的瓶頸。
越短的時間內執行的次數越多越容易體現出來。
釋出到Nuget2周時間不到
我已經提交了這麼多次修改
SqlSugar的用法和介簡:http://www.cnblogs.com/sunkaixuan/p/5654695.html ,歡迎您的建議
最後我只想說一句,不是第三方ORM不能用,而是你們並沒有把問題指出來,程式碼開源就是為了讓大家一起進步,一起改進。
只要作者有激情,有上進心,還擔心什麼呢。