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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何用EFCore Lazy Loading实现Entity Split

發(fā)布時間:2023/12/4 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何用EFCore Lazy Loading实现Entity Split 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

α角 與 β角

支持 現(xiàn)實生活 的 計算機(jī)系統(tǒng),總有著兩大偏差,第一個是?現(xiàn)實生活?與?計算機(jī)系統(tǒng)?的α角,另外一個是計算機(jī)系統(tǒng)的?邏輯設(shè)計?與?物理設(shè)計?的β角。舉個栗子:

  • α角:假設(shè)某個公司的商業(yè)流程,我們在做計算機(jī)自動化的時候,會發(fā)生某種程度的改變。可能是用了新計算機(jī)系統(tǒng),需要調(diào)整商業(yè)流程;也可能是某些商業(yè)流程,由于種種原因,沒有被計算機(jī)系統(tǒng)實現(xiàn)支持。。。

  • β角:這個比較常見,例如某個類本身是沒有什么ID之類的屬性,而由于我們選擇了某個數(shù)據(jù)庫產(chǎn)品來做持久化,而數(shù)據(jù)表的主鍵用了 某某ID 這樣的字段,于是引致我們的 類 里面也可能會包含了 ID 這樣的屬性;或者由于需要用 SQL Server 的 數(shù)據(jù)復(fù)制 功能,從而使到我們的類加入了各種TimeStamp字段

Entity Split

今天我們討論的Entity Split,就是屬于上述的β角。有時候,由于某些原因(例如 縱向切割 數(shù)據(jù)表),某個 類 ,它被保存到超過一個的數(shù)據(jù)表中。例如,我們可能有一個 Customer 類,由于它的屬性比較多,于是為了提供系統(tǒng)性能,我們把最常用的屬性歸納到 Customers 數(shù)據(jù)表,而把那些比較少用到的屬性歸納到 CustomerOtherInfo 數(shù)據(jù)表,等等。
在用EF Core的時候,我們會在DbContext.OnModelCreating方法里面用modelBuilder.Entity<MyEntity>().ToTable("Tablename");的做法來指定 BusinessEntity 與 數(shù)據(jù)表 的映射關(guān)系,但是這個只能是Entity級別的,而沒有能去到 屬性 級別啊 。如何才能做得到指定 “某Entity的某些屬性,映射到數(shù)據(jù)表A;而某些其他屬性,映射到數(shù)據(jù)表B”,這樣的效果呢?
(本篇的程序,可以在?https://github.com/kentliu2007/EFCoreDemo/tree/master/EntitySplit?上下載,我用的是 VS2017。建議可以下載之后,對照著程序來閱讀本篇)

數(shù)據(jù)表

先來看看數(shù)據(jù)表是怎樣的:

  • Clients 表的索引

  • ClientContactInfo 表的索引

  • 外鍵FK_ClientContactInfo_Clients的設(shè)置

如何用EF5/6實現(xiàn) Entity Split

首先讓我們先來看看 EF5/6 是怎么實現(xiàn)的。
如果用EF5/6的話,這個很簡單。因為有設(shè)計器啊,TableMapping就可以輕松搞定。

  • 項目文件:

  • EF Diagram:

  • UnitTest程序:

    看,程序完全不需要考慮數(shù)據(jù)是來源于不同的兩個數(shù)據(jù)表。簡單吧?

如何用EFCore 實現(xiàn) Entity Split

用EF Core,沒有設(shè)計器,怎么搞?其實,就算有設(shè)計器,也不能和EF5/6那樣的實現(xiàn)方式的。
這里我們需要先請出 EF Core的一個重大功能 Lazy Loading。這個功能從EF Core V2 開始支持。

EF Core Lazy Loading
  • 文檔:https://docs.microsoft.com/zh-cn/ef/core/querying/related-data#lazy-loading

  • 它有兩種實現(xiàn)方式,

    • 一種是用Microsoft.EntityFrameworkCore.Proxies包,以及調(diào)用UseLazyLoadingProxies來啟用這個包。并且要求類里面的NavigationProperty需要是public且virtual

    • 另外一種使用 Microsoft.EntityFrameworkCore.Abstractions 包中定義的 ILazyLoader 服務(wù)的引用。這個需要類里面做更多的特定代碼來支持

上述兩種做法各有利弊,所以我們接下來會針對兩個做法都分別用一次。用它們來實現(xiàn) 基于 EF Core的Entity Split

可行性分析

通過上面分析的EFCore里面ToTable的做法,我們知道,實際上是真的不可避免地需要有倆 Entity ,這樣才可以設(shè)置它們分別映射到不同的數(shù)據(jù)表。然后,因為有了Lazy Loading,我們可以對 Client 這個?主類?,添加引用 ClientContactInfo 類的相應(yīng)的幾個屬性。通過玩弄getter和setter的把戲。讓EFCore的Lazy Loading在getter/setter調(diào)用到ClientContactInfo的屬性的時候,按需裝載,這樣又可以實現(xiàn)Entity Split,系統(tǒng)性能也得到好處。

用Microsoft.EntityFrameworkCore.Proxies來實現(xiàn)EFCore的Entity Split
  • 項目文件:

  • 程序:

    • DbContext:

    • ClientContactInfo:

    • Client:

    • UnitTest:

      看上面UnitTest的程序,就看出來,我們程序調(diào)用Client的時候,完全不需要考慮數(shù)據(jù)是來源于不同的兩個數(shù)據(jù)表。Entity Split就這樣搞定了。
      用Microsoft.EntityFrameworkCore.Proxies的缺點是,我們需要有Client.ClientContactInfo這個NavigationProperty。而且還有另外一個可能的坑(如果你嘗試調(diào)用Client.ClientContactInfo.GetType()就知道了,這個我們可以以后再特別弄個隨筆來吐槽一下)。
      接下來,為了維持OOP的美式咖啡口味,讓我們換個Lazy Loading的實現(xiàn)方法。

用Microsoft.EntityFrameworkCore.Abstractions來實現(xiàn)EFCore的Entity Split
  • 項目文件:

  • 程序:

    • DbContext (這個和上面那個例子一樣,就不騙篇幅了,大家繼續(xù)參照上面那個Lazy Loading做法的貼圖就好)

    • ClientContactInfo(這個和上面那個例子一樣,就不騙篇幅了,大家繼續(xù)參照上面那個Lazy Loading做法的貼圖就好)

    • PocoLoadingExtensions (這個是直接抄微軟文檔上的,所以我也不騙篇幅,大家直接參閱上述微軟文檔的內(nèi)容就好。網(wǎng)頁上查找一下PocoLoadingExtensions這個文本就能找到了)

    • Client:

      程序里面用了一個private field來存放 ClientContactInfo的 實例,然后用了一個private的ClientContactInfo的property(通過繼續(xù)玩弄它的getter/setter的把戲來幫忙提高程序的可維護(hù)性)

    • UnitTest(這個和上面那個例子一樣,就不騙篇幅了,大家繼續(xù)參照上面那個Lazy Loading做法的貼圖就好)
      用Microsoft.EntityFrameworkCore.Abstractions的缺點是,我們的類里面需要加入一些額外的程序(為了支持ILazyLoader )。但是好處是,Client的public屬性里面,再也沒有ClientContactInfo這種NavigationProperty了。就真的是毫無痕跡地實現(xiàn)了Entity Split。

結(jié)語

怎么樣?EF Core真的很棒,對吧?借助Lazy Loading的功能,我們花費了一些周折,如此簡單地實現(xiàn)了Entity Split。
當(dāng)然,我本人還是希望Entity Split這個可以built-in為EF Core的一個基本功能,而不是采取借助Lazy Loading這樣的Walk Around做法。也許接下來的第N個版本,它就會實現(xiàn)的。畢竟"面包會有的,牛奶會有的,一切都會有的。" :-P
下一篇,讓我們繼續(xù)討論,如何借助Lazy Loading,在用EF Core的Inheritance功能的時候,繼續(xù)保持?jǐn)?shù)據(jù)表的清潔(不需要有冗余的字段)。敬請期待噢。 :-D

相關(guān)文章:

  • Shadow Properties之美(一)【Microsoft Entity Framework Core隨筆】

  • Shadow Properties之美(二)【Microsoft Entity Framework Core隨筆】

  • “幕后英雄”之Backing Fields【Microsoft Entity Framework Core隨筆】

原文地址:https://www.cnblogs.com/fatkent/p/10365659.html

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


總結(jié)

以上是生活随笔為你收集整理的如何用EFCore Lazy Loading实现Entity Split的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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