Entity Framwork(EF)一直以來毀譽參半,有些人喜歡它,不過有些人認為它與NHibernate、LINQ-to-SQL和其他小型ORM框架相比沒有什么優勢。EF Core在早期給人們留下糟糕的印象,也一直讓那些對EF有所期待的人大失所望。
SQL生成
EF最糟糕的一點是對SQL生成這一功能支持不足,而EF Core 2.0仍然不支持最基本的SQL組建功能(比如group)。雖說ORM框架不支持一些高級特性(如Window Functions)是很正常的,但無法處理像“GROUP BY”這樣的功能對于大部分開發者來說是無法接受的。
版本說明里提到,這一版本“增加了一些SQL映射模式,之前版本里很多會觸發客戶端求值的查詢在2.0里不會再有類似的行為”。不過,他們并沒有提及這些模式的具體細節,所以我們建議開發者要小心對待每一個查詢。當然,你也可以禁用客戶端求值。
微軟方面指出,他們計劃在EF Core 2.1里支持group特性。
復雜類型(Complex Type)
EF里有復雜類型的概念,開發者可以創建映射到同一張表的子對象。它的用處之一就是用來把常用的審計字段和一般的數據字段分開。
EF Core并不支持復雜類型,不過它提供了“Owned”和“Child”類型。微軟的Diego B Vega說,“EF Core 2.0的Owned類型支持之前EF版本的復雜類型所能支持的所有場景”。不過,它們的語法不太一樣,而且模型設計得太過復雜,需要花更多的時間來學習它們。
懶加載
懶加載被很多人認為是一個糟糕的設計,因為它會導致性能問題(比如1+N查詢問題)和運行時錯誤(比如上下文被銷毀)。盡管如此,它仍然是EF里非常受歡迎的一個特性,有些人認為,如果一個ORM框架不支持這一特性,那么它就算不上一個真正的ORM框架。所以把懶加載推遲到EF Core 2.1這一決定也難怪會讓他們感到不安。
微軟的Rowan Miller說開發者可以創建自己的懶加載機制。
雖然2.0不支持懶加載,不過我們提供了一些特性,可以通過這些特性來實現懶加載。其中最重要的一個就是Life Cycle Hooks,再結合我們在1.1版本里就已引入的EntityEntry API,就可以實現一個初步的懶加載。
不過,用于具體化對象的Life Cycle Hooks目前還只是EF Core 2.1的“延展目標”。
Table Per Type
Table Per Type(TPT)繼承模式可以讓一個邏輯記錄跨越多個數據庫表。一個抽象的基類代表一張表,而每一個子類都有自己對應的表。這樣一來,在數據庫設計上就會更有效率,而應用程序也能看到數據的邏輯視圖。
不過,TPT在EF里有嚴重的性能問題。以下的抱怨內容來自User Voice。
隨著子類數量的增長,生成SQL需要花費更長時間,SQL查詢也變得越來越復雜,難以管理。一個簡單的基類(5到6個字段)和大約30個左右的簡單子類(2到3個字段)就需要2分鐘來生成和執行(ObjectQuery.ToTraceString())。EF會為基類的一個簡單SELECT查詢生成8000行SQL代碼,生成的SQL里有很多子查詢、join和union。即使是空表(查詢不返回數據),它也需要那么多時間來生成和執行SQL。
這里的大部分問題都已經得到修復,不過EF 6已經過時了,微軟在這方面也沒有計劃投入更多的資源。
EF Core完全不支持TPT,盡管這一特性已經包含在backlog里,但并沒有具體的實現計劃。這對于已經在EF里使用TPT的開發者來說會是個問題,因為他們需要作出重大修改。
Table Per Concrete Class
與TPT相關的另一個特性是TPC,也就是Table Per Concrete Class。與TPT類似,它也是通過繼承關系來簡化類的設計。不過,在數據庫端并沒有相應的表來表示抽象基類。每一個具體的子類與自己的一張表相對應,這張表包含了子類本身和所有父類的字段。
EF Core也不支持TPC,不過似乎沒有太多人對此提出看法,可能是因為開發者可以很容易地使用接口來代替抽象基類。基類的屬性可以被剪切和拷貝到子類里,雖然這樣做很繁瑣,但也并沒有什么問題。
存儲過程
另一個缺失的特性是對存儲過程的支持。盡管存儲過程有可能被濫用,但對于關系型數據庫來說,它仍然是一個強大的工具。在很多情況下,直接在數據庫端處理數據要比把數據傳送到應用程序里再處理高效得多。特別是當一個事務需要鎖定多個表,并多次傳送數據的時候,存儲過程的優勢就更為明顯。
這個特性看起來似乎是很容易實現的,因為生成這樣的SQL非常簡單。InfoQ通過DLR來演示一個小型ORM僅使用了200行代碼。不過,目前這一特性也只是在backlog中,沒有具體的實現計劃。
因為有臨時解決方案的存在,所以這一特性的優先級不會很高。Anuraj P演示了如何在EF Core里調用存儲過程,以及如何解決缺乏命名參數的痛點。
空間類型
EF Core不支持空間數據,雖然它的路線圖賦予這一特性較高的優先級,但并沒有具體的發布計劃。
查看英文原文: Entity Framework Core 2.0 Released to Heavy Criticism