ServiceStack.OrmLite


ServiceStack.OrmLite 

談談我的入門級實體框架Loogn.OrmLite

 

    每次看到有新的ORM的時候,我總會留意一下,因為自己也寫過一個這樣的框架,人總是有比較之心的。我可能會down下來跑一跑,也可能不會這么做,這個取決於跑起來的難易程度。我是很懶的,有XML配置或其他稍微不直觀的設置的,我總是懶得看。每當筆者談論自己的ORM的時候,總會拿EF和Dapper說事兒,EF算官方的吧,Dapper則以效率著稱。但是我很奇怪為什么ServiceStack.OrmLite這么NB的一個ORM卻鮮為人提。我真想為它說一句話:.net的ORM框架中有一個非常優秀的成員叫ServiceStack.OrmLite !

    我知道ServiceStack.OrmLite已是好幾年前的事了。初次見面,甚是歡喜,以為找到了可以長久使用的ORM,喜歡它那簡潔的API和超高的效率。在我打算愛上它的時候,發現了一個令我很不爽的地方:它的方法重載太多,其中有幾個VS的智能提示區分不出來是哪個重載了,而這個方法的參數正好是需要提示的Lambda表達式,這一點一直使我耿耿於懷,沒用上它。Loogn.OrmLite的名稱和API都參考了它。

    我寫過好多版本的數據訪問組件,感覺從畢業了就一直在寫,當然,都是很簡單的代碼,包括現在這個OrmLite,我感覺自己寫不出什么高深的代碼。剛畢業的學生,如果會if else等C#基礎,會簡單的封裝繼承多態,就可以看懂。個人的ORM,風格上很大一部分受作者主觀意識和遇境的影響,這都是很正常的,自己喜歡就好。比如我的ORM開始只支持MSSql,因為我到那個時候為止只用過mssql,后來一家公司要用MySql,於是花了兩個小時讓它支持mysql,前段時間又感覺sqlite這樣一個本地數據庫還是挺常用的,又花了一個小時讓它支持sqlite。我一個朋友hubro也寫了一個叫CRL的ORM,他那里面支持了mongodb,理由是這樣就可以統一訪問了。但我就不會支持(我和ServiceStack一樣,是用擴展方法,沒有自己的一層抽象,所以也實現不了,哈哈),因為我感覺mongodb的C#客戶端封裝的已經不錯了,頂多在項目里面寫個幫助類就可以到處跑了,我以前用mongodb就是這么干的。所以,個人的ORM都有自己的風格。

***********************************************************************

    我先把效率測試結果貼出來,讓大家有個底兒,讓大家知道入門級的東西的效率也是不錯的,然后接着敘:

    注:測試代碼源自Chloe.ORM ,有現成東西我習慣性會借用。還要謝謝Chloe.ORM的作者,就是在用作者的效率測試程序后,決定把自己的mapping改進了,中間還鬧了笑話,哈哈!

    注:記得園子里還有個CYQ.Data,也想一並測試了,但是得到MDataTable對象后,調用ToList的時候有點問題,Guid類型和String類型兩個字段沒賦值成功,后來好像還報了個類型轉換錯誤,就沒跑起來,我是在nuget里下載的引用(作者看到可親測一下,也許是我哪里沒搞好)

    注:源碼以及測試代碼

  

1、Mapping count:5000000 表示一次查詢出5000000條記錄,測試mapping效率。可以看出效率基本差不多,ChloeSql和ServiceStack突出了一點,CRL最慢的原因是實體類有繼承基類,大家知道,實例化對象的時候所有父類對象都必須實例化。

2、Query count :20000,Limit 10 表示查詢20000次,每次查詢10條記錄。Dapper和ServiceStack的效率是超級棒的,最棒的是Loogn的(不太會吹NB,只能吹到這個程度了)

3、SingleContextQuery count:20000,Limit 10 表示在一個上下文中查詢20000次,每次查詢10條記錄。Dapper和ServiceStack的效率還是超級棒的,最棒的還是Loogn的(剛開始學吹NB,還不熟練)

***********************************************************************

      好我不吹牛逼,吹牛逼不是我的強項,我繼續說相關的東西。

      從上面的查詢測試結果來看,Loogn.OrmLite是非常快的。為什么會這么快呢,就是因為它代碼簡單。都說自己的dll小,而Loogn.OrmLite.dll只有70多kb,是Dapper.dll的1/2,其他的可自行比較。當然功能也很簡單,比如EF、Chloe.NET、CRL、ServiceStack都支持lambda表達式查詢,我的就不支持。我承認Expression是一個非常好的特性,但是本人水平有限再加上很懶,一直不想涉足這塊,簡單的查詢還好解析,復雜的查詢不太好解析,或者調用起來很別扭,我不喜歡只支持一半的東西(當然,這都是自己安慰自己的理由,說白了還是能力不夠),所以我以后也不打算支持。

 

    他們的好像都封裝了連接查詢,而我的只是用sql語句來實現。關於連接查詢返回多表數據如何接收的問題,EF和Chloe.NET好像都是用的匿名對象,這種返回值寫起來很優雅,但是如果把返回值再傳遞一下(比如傳遞給另一個方法),智能提示就用不上了。CRL的好像是有一個主實體類,連接查詢的其他附加字段通過這個主實體類的一個字典來保存,為了獲取方便且在同一層級,還貼心地提供一個以string為參數的索引器來取值(比如user.exts["name"] 可以寫成 user["name"]),這種方法以前我有用過,感覺還不錯,但也不太喜歡。而Loogn.OrmLite根本沒有顧及這些,只能一個查詢映射到一個類,可以給這個類添加冗余屬性來接收連接查詢的他表字段,但是要加[OrmLiteField(Ignore = true)]特性。Loogn.OrmLite也可以返回dynamic或List<dynamic>類型,但實際開發中我基本沒用過,動態類型的返回值在寫demo或數據遷移的時候很方便,不用定義實體類了!其實在開發中,我已經很少用表連接了,要取多表數據怎么辦呢?

第一種是可緩存的:比如新聞表有TypeID,另外還有個新聞類型表,在顯示新聞的時候需要顯示新聞類型的名稱。這種情況的特點是另一個表的數據不常變動且很少,這里就可以把新聞類型表的數據緩存起來,在內存中操作,當然要處理好緩存過期的情況。

第二種是可冗余的:比如收藏文章,可以把文章標題也冗余的存儲到收藏表里。

第三種是可id in 查詢的:這種情況不適合查詢3張表以上的,而且最好是id關聯的,查出主表,獲取ids,用 in 查詢另一張表,然后再通過id關聯,這些集合操作用lambda是很容易實現的,Loogn.OrmLite里有提供SelectByIds這樣的方法,所以我比較常用。

可能還有其他情況的處理方法,如果沒一個好的方法,直接用連接查詢也沒什么!

 

    Mapping部分我的應該是最容易理解的了(在達到這個效率的前提下)。一般為了高效映射,作者都會運用傳說中的黑暗魔法--IL。特別是Dapper,運用的很巧妙(Chloe.ORM應該借鑒了Dapper)。但是做為入門級框架寫不出那樣的代碼。后來想想,數據庫字段的類型也就那幾種,於是就笨手笨腳的寫了20多個強類型委托訪問器,摘錄基類和一對訪問器如下:

其實就是一個多態的運用,理解起來還是很簡單的,倒是[復制][粘貼][修改]費了不少時間。。。。。。

 

    我基本沒有用設計模式。檢測這個有一個簡單有效的方法,打開源碼,隨便找幾個方法,按幾次F12,看能不能都找到具體實現就知道了。用設計模式一般會基於接口、抽象類編程,這是一種非常好的編程方法,但是從一個初學者來說,或者像我這樣直腦子的人來說,F12找不到具體實現總是感到很迷茫。我在支持mysql和sqlite的時候,完全是用if else判斷來區分不同的代碼邏輯的,比如一些語法不同的地方。這樣的代碼很挫,比如再支持一個Oracle數據庫,我只能在每個這樣的判斷下面寫更多的判斷(所以新手要引以為戒)。目前這樣的代碼工作還算良好,等我水平達到了說不定會重構一下。

   整篇下來,好像也沒介紹多少關於我自己的框架,我的本意正是如此。一個原因是它功能簡單,實在不知道說什么;另一個原因是我感覺使用個人框架一定要謹慎,別人寫的東西只有非常了解才能運用自如,避免缺陷和誤用功能。關於推薦,雖然我可能會一直用自己的,但還是首推EF。EF功能強大,上手極快,知名度高,語法優美,效率也不是什么大問題,我相信好多個人ORM也借鑒了EF。ServiceStack那個因為智能提示讓我耿耿於懷,也不敢向大家推薦了,有興趣的可自行把玩。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM