由于破壞了向后兼容性,Entity Framework的名聲相當不光彩,但與Entity Framework Core的完全重寫相比就相形見絀了。在本文中,InfoQ將著眼于其中部分主要特性的變化及其影響。
延期及棄用的特性
首先,我們將看下那些EF Core 1.0沒有支持并且也不在EF Core 1.1路線圖上的EF 6特性。
延遲加載
一般來說,對于Entity Framework和ORM而言,延遲加載一直是一個備受爭議的問題。EF最初就不應該支持延遲加載,因為它很容易被誤用,而且經常導致性能問題。
不過,在性能不是很重要的情況下,比如快速原型和實用工具,延遲加載還是非常有用的。因此,第二個主要版本EF 4增加了這一特性。(注意:為了與.NET Framework的版本號保持一致,EF跳過了版本2和3。)
EF Core沒有提供延遲加載,這讓一些人歡呼,也讓其他人錯愕。目前的建議是等待EF Core 1.1,到時候,他們“可能會允許你推出自己的延遲加載。”根據GitHub及其他地方的各種討論,還不清楚他們是否會直接支持它。
GROUP BY轉譯
這一點令人難以理解。雖然LINQ to SQL在10年前就提供了支持,但EF Core的路線圖上并沒有GROUP BY支持。這意味著,如果你的查詢中包含分組操作,EF Core將在查詢生成的時候忽略GROUP BY子句。
顯而易見的結果是,這將極大地增加網絡帶寬要求,因為所有的底層數據都需要在聚合之前移到中間層。反序列化額外的數據也是有開銷的,而且,在執行實際的分組操作時,C#的效率很有可能比數據庫低。(數據庫的優勢是可以使用表的統計信息,如表的大小和分布,確定使用的最佳算法。)
存儲過程
微軟另一個讓人吃驚的舉措是不支持存儲過程。雖然從技術上講你仍然可以使用原始SQL訪問它們,但那有許多限制。
SQL查詢只能用于返回作為模型組成部分的實體類型。[該特性計劃在.NET Core 1.1中提供。] SQL查詢必須為實體類型的所有屬性返回數據。 結果集中的列名必須與屬性映射的列名相匹配。注意,這點和EF6.x不同。在EF6.X中,在使用原始SQL查詢時,屬性/列映射會被忽略,結果集列名必須和屬性名匹配。 SQL查詢不能包含關聯數據。然而,在許多情況下,你可以使用Include操作符組合查詢返回關聯數據(參見“包含關聯數據”)。在某些情況下,你可以將原始SQL和LINQ表達式混合,比如向表-值函數查詢添加Where或OrderBy調用。
空間數據類型
空間數據類型的情況比較有趣。當直接使用ADO.NET時,他們希望開發人員使用隨SQL Server提供的、作為COM庫(Microsoft.SqlServer.Types)封裝器的空間類型。由于COM不能很好地與.NET融合,尤其是在庫的分發和注冊要求方面,所以Entity Framework平行開發了自己的空間類型(System.Data.Spatial)集。這兩種API都是以開放地理空間聯盟(OGC)規范為基礎,因此在基本功能方面非常相似。
目前為止,我們討論的內容主要和SQL Server相關。其他數據庫會有其他的空間類型實現。因此,就可以理解,微軟為什么正在花時間設法解決這個問題。
種子數據
雖然EF Core支持數據庫遷移,但不支持操作種子數據查找表。
簡單命令攔截
命令攔截廣泛應用于消除Entity Framework SQL生成器的局限。例如,如果你希望在EF中使用全文搜索,則需要實現IDbCommandInterceptor接口,并重寫ReaderExecuting/ScalarExecuting方法。
這項技術相當復雜,而且嚴重依賴于確切地知道EF會生成什么SQL。但是,沒有這項技術,數據庫的許多高級特性都無法使用了。
工具
之前的文章中已經提到過,最初隨LINQ to SQL和Entity Framework提供的圖形建模工具不會出現在EF Core中。
而且,目前沒有計劃提供從數據庫更新模型的能力。在可預見的未來,從數據庫生成模型仍然會是一個一次性事件。
EF Core 1.1的特性
EF Core 1.1有望在明年1季度發布,除了Bug修復外,還包含以下特性。
改進轉譯
這個麻煩的標題缺少細節信息。它只是介紹說,“讓更多的查詢成功執行,在數據庫(而不是內存)中進行更多的邏輯求值。”它還介紹說,EF 6支持“簡單”、“中等”和“復雜”查詢。EF Core的中等查詢已經“穩定”,復雜查詢支持還在開發中。
關于涵蓋哪些場景的線索很少,所以開發人員需要格外仔細地檢查生成的SQL,并分析它們的數據庫調用,以確保EF行為正常。
類似地,使用了導航屬性的查詢被認為仍處于開發中。
查詢非模型類型
如上文所述,EF Core 1.1有望能夠物化不是模型組成部分的類型。
DbSet.Find
這是EF 5提供的一個方便的方法,用于通過主鍵加載記錄,無需顯式指定名稱。它鉤入上下文緩存,因此避免了不必要的數據庫調用。它還可以找到已經附加到上下文但尚未保存到數據庫(前提是你沒有使用identity/auto-number列)的記錄。
EntityEntry/ObjectStateEntry APIs
更多EntityEntry及ObjectStateEntry特性,如Reload、GetModifiedProperties、GetDatabaseValues,同樣也在計劃里。
顯式加載
不要同“主動加載”混淆,顯式加載允許將子集合加載到已經物化的實體中。可以將它看成是延遲加載外加一個額外的步驟。
連接恢復能力
這是一個很有前景的特性,它會自動重試因為連接問題導致失敗的事務。“這在連接到SQL Azure時特別有用,在那種情況下,瞬時錯誤很常見。”
EF Core下一個版本的特性
雖然預計不會在EF Core 1.1的時間框架內完成,但有些其他的特性正在準備中:
復雜/值類型是沒有主鍵的類型,用于表示實體類型上的一組屬性; 簡單類型轉換,如string=>xml; 從已有的數據庫進行模型逆向工程的Visual Studio向導。查看英文原文:Delayed and Deprecated Features in Entity Framework Core