日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

NET主流ORM框架分析

發(fā)布時間:2023/12/4 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NET主流ORM框架分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

接上文我們測試了各個ORM框架的性能,大家可以很直觀的看到各個ORM框架與原生的ADO.NET在境刪改查的性能差異。這里和大家分享下我對ORM框架的理解及一些使用經(jīng)驗。

    ORM框架工作原理

    所有的ORM框架的工作原理都離不開下面這張圖,只是每個框架的實現(xiàn)程度不同但是最終的目的是相同的。

    如果是一個ORM框架那么一定會有上圖中藍色部分的這幾個元素,無論是增刪改查對于ORM一定是以對象為起點,使用對象構(gòu)造出LINQ表達式,這樣我們在對象的世界中可以描述我們希望對數(shù)據(jù)庫所進行的操作,LINQ的最終實現(xiàn)其實也是Lambda表達式(必盡LINQ在代碼上會直觀很多),功能較強的ORM中都會記錄有對象類型到數(shù)據(jù)庫對象的元數(shù)據(jù),使用這些元數(shù)據(jù)可以將復(fù)雜的Lambda表達式翻譯成一個通用的中間表達式,這個表達式其實是抽象于各個不同數(shù)據(jù)庫的具體實現(xiàn),最后中間表達式再按指定數(shù)據(jù)庫的具體實現(xiàn)生成最終的SQL語句,交由ADO.NET對象執(zhí)行到數(shù)據(jù)庫,如果數(shù)據(jù)存在返回則會回寫到CLR對象中。

    以上概括了所有ORM的實現(xiàn)過程,這里比較典型的是Dapper,它之所以小巧而高性能的原因正是因為該框架中沒有綠色的部分,可以說是所有ORM框架中最為精簡的(可能還會存在其他類似的框架,這里僅用Dapper作為典型案例說明),因此沒有多余的部分自然小而快。然而綠色部分的存在就決定了該ORM框架的功能到底有多強,剛好目前世面上的ORM框架中只有EF是完全實現(xiàn)了綠色框中的各個元素,并且支持最為全面,所以EF必然重而慢(至少EF6相對其他框架是比較差的)。

    典型ORM框架實現(xiàn)

  • ?Dapper:需要自己手寫SQL語句完成操作,比較簡單直接不過還有DapperExtensions的幫助,可以在插入、修改及刪除時不用寫SQL語句全對象操作,這里需要指出的是它應(yīng)該不能算是一個完全的ORM框架,因為日常開發(fā)占比多的查詢還是需要手寫SQL,無法對象類型化。

  • Nhibernate:這是個比較久遠的框架,該框架需要自己配置元數(shù)據(jù)功能上會比DapperExtensions強一點,不過對于查詢表達式?jīng)]有太好的支持。

  • SqlSugar,Chloe.ORM:此類框架雖然不能支持LINQ但是可以實現(xiàn)自己一套Lambda表達式用于生成SQL語句,總之其總體思想就是把SQL語法轉(zhuǎn)換成表達式語法,比較典型的是會用表達式中的變量名用作生成SQL語句中的別名,而且附加功能會比較多,總之比較靈活實用。

  • Linq2db:此類ORM算是實現(xiàn)的比較完整的ORM流程(見上圖),而且支持眾多的數(shù)據(jù)庫,總之功能算是比較強大了。

  • EF功能最強的ORM

    ?EF是目前為止功能最強的ORM,這個相信大家沒有什么爭議,大家可以參考一下這份文檔 (EF Core and EF6 Feature by Feature Comparison),其中列出了EF6與EFCore的功能特性,相信沒有哪個ORM框架實現(xiàn)了其中大部分的特性,下面隨便列舉幾個特性:

    • 全面支持LINQ查詢,有不少框架也會支持LINQ可是使用時會發(fā)現(xiàn)有些寫法是不支持的,但是EF是目前支持最全的,在截止到目前為止EFCore的正式版本中也沒有完全實現(xiàn)EF6對LINQ的支持。

    • EFCore性能提升:從上一遍博客(Mego(1))中可以看出對于個功能強大的ORM框架而言EFCore已提升相當多了總之已非常接近原生的ADO.NET框架了。

    • 對象繼承:這是個很好的設(shè)計,它可以讓你將關(guān)系數(shù)據(jù)庫實現(xiàn)對象繼承化,在數(shù)據(jù)表中也會存在等價父子表。

    • 數(shù)據(jù)庫遷移功能,無論你怎么看待這個功能,但是對于開發(fā)而言這個功能太實用了,相信大家在很多DEMO中可以見到使用EF生成數(shù)據(jù)庫。

    • 對象的集合屬性展開,通常我們在取訂單時也希望一起把明細也取出來,更多的情況是還可以把訂單數(shù)據(jù)分頁,這個功能在大部ORM都是沒有的需要自己處理,然后在EF中只需要寫一行代碼就能搞定。

    • 多對多關(guān)系:這個也是個比較常用但是也在其他ORM比較少見的功能,EF也是目前支持最好的。

    • EF框架對接了微軟的眾多其他需要數(shù)據(jù)訪問的框架,例如ASP.NET Identity,ASP.NET WebApi ODATA。

    EF與EFCore缺陷

    ?雖然EF或EFCore功能已經(jīng)很強大了,不過在開發(fā)過程中還有很多不足的地方,也有很多缺陷這也是導(dǎo)致有很多人使用之后而放棄的原因之一(當然還有EF6的性能問題)。下面將列一下EF6的不足給大家參考。

    數(shù)據(jù)更新功能不足

    在EF中數(shù)據(jù)提交的功能一直不行,在EF6中所有的數(shù)據(jù)操作都是單個對象分別提交了,這也就表示在大量數(shù)據(jù)提交過程中每個對象都要發(fā)送一次數(shù)據(jù)庫,這也是導(dǎo)致為什么性能底下了,而且更新及刪除數(shù)據(jù)一定要從數(shù)據(jù)庫取回對象或附加對象才能操作。這個問題在EFCore中都得到解決而且性能比較好如前文的測試可見。但是EF到目前都不能支持條件更新、條件刪除。不過這個問題可以使用這個框架(Entity Framework Plus)解決,不過這個框架是收費的。

    創(chuàng)建時間修改時間問題

    ?我們在業(yè)務(wù)系統(tǒng)開發(fā)時常會遇到創(chuàng)建和更新數(shù)據(jù)時需要記錄創(chuàng)建時間或修改時間的情況,不過目前無論是EF或EFCore中都只能用觸發(fā)器來解決,不過當數(shù)據(jù)表變多時維護這些觸發(fā)器也是個比較麻煩的事情。有人會想到用默認值,這個EF中是支持的,但是EF不能選擇性的插入或更新指定的字段,這是個兩難的情況。

    創(chuàng)建及修改時間只是這類問題的一個例子,這類問題可以概括為我們在插入或更新數(shù)據(jù)時希望指定字段是調(diào)用相應(yīng)的數(shù)據(jù)表達式生成的,而不是應(yīng)用程序的值,這里可以舉個實例給大家看,在一個負載均衡的架構(gòu)中我們需要在創(chuàng)建訂單時生成訂單流水號,這個流水號一定要唯一且連續(xù),在這種多服務(wù)器并發(fā)的情況下只有在數(shù)據(jù)庫生成這個流水號才是比較好的選擇,這樣可以充分保證當提交失敗時新分的流水號可以歸還,同時也保證大家依次生成不會重復(fù)且連續(xù),這個時候就很需要ORM可以自動使用單號生成函數(shù)來生成值。

    EF中的曲線解決,在EF6中插入、更改或刪除操作是支持存儲過程映射的,大家可以參考這個文章(Entity Framework Code First Insert, Update, and Delete Stored Procedures (EF6 onwards))里面有詳細的說明,這里我們可以做文章,我們修改存儲過程改為調(diào)用我們指定的表達式即可,這樣可以不用觸發(fā)器,也能達到目的。這里有人會問維護存儲也需要比較大代價,這里我們可以重寫EF的數(shù)據(jù)庫遷移生成存儲過程的代碼來統(tǒng)一處理。

    實體集合屬性多層展開

    ?無論是EF或EFCore中有一個Include函數(shù),用來在返回實體對象時顯示包含它的集合或?qū)ο髮傩?#xff0c;這個操作被稱為屬性展開,這里先這么稱呼。不過可以展開對象屬性(例如訂單 -> 客戶?-> 負責(zé)人?-> 公司),也可以展開集合屬性(例如 訂單?-> 明細集合),這時集合下面的屬性就不能展開了例如我希望得到(例如 訂單?-> 明細集合?-> 產(chǎn)品)這是不支持的。

    補充EF實際內(nèi)部代碼是可以支持這種操作但是沒公開,如果有對ASP.NET WebApi OData有所了解的朋友可以知道,如果你的OData服務(wù)是建立在EF基礎(chǔ)之上的,在ODATA語法中可以支持多級數(shù)據(jù)展開的,并且在EF6中得到很好的實現(xiàn),不過這些的前提是你的數(shù)據(jù)庫是SQL Server。

    對象關(guān)系限制

    例如一個訂單會有多個明細,每個明細都會對應(yīng)一個產(chǎn)品,從邏輯上我們就可以認為訂單和產(chǎn)品是多對多關(guān)系了,但是在EF中就沒有這么自由的可以操作了。

    在EF中關(guān)系的操作有很多限制,這個特別在多對多關(guān)系中很嚴重,EF6中會生成一個隱藏的關(guān)系實體用來建立關(guān)聯(lián),這些都是你不能控制的,而且在關(guān)系鏈接中要求主表一定要是主鍵,不過在EFCore中這些問題得到一些解決,不過EFCore目前不能支持多對多關(guān)系,至少目前的Flush API中還沒有看到。

    時間戳

    感覺EF中不少特性都是為SQL Server設(shè)計的,EF中強制時間戳必須CLR屬性是字節(jié)數(shù)組,不過在MySQL中的時間戳其實就是日期時間。

    多數(shù)據(jù)庫實現(xiàn)差異

    EF和EFCore是支持多個數(shù)據(jù)庫,其原理是EF定義的前文所說的中間表達式,然后再交給各方自行實現(xiàn)后續(xù)的操作。這種設(shè)計有如下缺點:

    • 數(shù)據(jù)庫支持綁定了數(shù)據(jù)訪問組件,例如MySQL.Data.Entity這個組件必須需要在MySQL.Data組件下工作,這時如果你想換個訪問MySQL的組件是不可以的。

    • 數(shù)據(jù)庫提供程序?qū)崿F(xiàn)代價太大,如果大家有時間可以去看下EntityFramework.SqlServer或MySQL.Data.Entity里的實現(xiàn)代碼,這些都是著名公司微軟和Oracle維護的代碼,其中的實現(xiàn)代碼非常復(fù)雜,對于一般的團隊而言可以算是一個非常大的項目。

    • 數(shù)據(jù)庫提供程序?qū)崿F(xiàn)質(zhì)量,還是以MySQL.Data.Entity為例子,每個提供程序并不像微軟那樣完全實現(xiàn)EF在SQL Server中的各個功能,而且代碼非常復(fù)雜問題會很多,即使是Oracle所維護的代碼也是同樣糟糕,下面分享MySQL.Data.Entity的兩個例子。

    MySQL.Data.Entity問題一:這個組件在MySQL5.6由于數(shù)據(jù)庫的主鍵限制在700多個字節(jié),因此它在自動遷移數(shù)據(jù)庫操作時會報錯主鍵過長錯誤,等于這個是完全不能用的。

    MySQL.Data.Entity問題二:這個組件在MySQL5.7中,由于數(shù)據(jù)庫的BUG(虛擬列如"SELECT 1"的IS NULL判斷錯誤問題)會導(dǎo)致特定的LINQ表達式生成的SQL腳本是不能得到正確結(jié)果的。

    MySQL.Data.Entity問題三:對于繼承的SQL生成這一部分是完全沒有實現(xiàn)的,你會發(fā)現(xiàn)所生成的腳本都是錯的。

    MySQL.Data.Entity問題四:EF的Include操作的具體實現(xiàn)是依賴于CROSS APPLY(SQL Server)語法的,不過MySQL中完全沒有,也很寫出替代語句,因此這個功能在MySQL下等于是不存在的。

    以上是因為我參加了EF對接MySQL的改造項目,這是我和我的團隊折騰了幾個月才得出的一些總結(jié),不過好在我們最后通過修改MySQL.Data.Entity源碼解決了這些問題。

    總之其他框架不能確定,但是在EF中各個數(shù)據(jù)庫的支持程度是很不對稱的。

    總結(jié)

    在EntityFramework長達10年的發(fā)展歷程中,開始發(fā)展很快,但是后面到EntityFramework6.1.3(2015年3月)這個版本時就好像是EntityFramework的結(jié)束,之后EntityFramework6就再沒有此實制上的更新了直到今天,應(yīng)該是微軟已經(jīng)放棄它轉(zhuǎn)向EntityFrameworkCore上,不過EntityFrameworkCore的發(fā)展也沒有這么快,至今還沒有超過EntityFramework6,所以直到今天微軟都不敢對外宣布放棄EntityFramework6。

    ?

    以上是我的個人見解,僅供參考。

    原文地址?http://www.cnblogs.com/CarefreeXT/p/8729085.html


    .NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com

    總結(jié)

    以上是生活随笔為你收集整理的NET主流ORM框架分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。