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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

编程问答

如何用EFCore Lazy Loading实现Entity Split

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

α角 與 β角

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

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

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

Entity Split

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

數(shù)據(jù)表

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

  • Clients 表的索引

  • ClientContactInfo 表的索引

  • 外鍵FK_ClientContactInfo_Clients的設(shè)置

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

首先讓我們先來(lái)看看 EF5/6 是怎么實(shí)現(xiàn)的。
如果用EF5/6的話,這個(gè)很簡(jiǎn)單。因?yàn)橛性O(shè)計(jì)器啊,TableMapping就可以輕松搞定。

  • 項(xiàng)目文件:

  • EF Diagram:

  • UnitTest程序:

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

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

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

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

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

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

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

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

可行性分析

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

用Microsoft.EntityFrameworkCore.Proxies來(lái)實(shí)現(xiàn)EFCore的Entity Split
  • 項(xiàng)目文件:

  • 程序:

    • DbContext:

    • ClientContactInfo:

    • Client:

    • UnitTest:

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

用Microsoft.EntityFrameworkCore.Abstractions來(lái)實(shí)現(xiàn)EFCore的Entity Split
  • 項(xiàng)目文件:

  • 程序:

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

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

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

    • Client:

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

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

結(jié)語(yǔ)

怎么樣?EF Core真的很棒,對(duì)吧?借助Lazy Loading的功能,我們花費(fèi)了一些周折,如此簡(jiǎn)單地實(shí)現(xiàn)了Entity Split。
當(dāng)然,我本人還是希望Entity Split這個(gè)可以built-in為EF Core的一個(gè)基本功能,而不是采取借助Lazy Loading這樣的Walk Around做法。也許接下來(lái)的第N個(gè)版本,它就會(huì)實(shí)現(xiàn)的。畢竟"面包會(huì)有的,牛奶會(huì)有的,一切都會(huì)有的。" :-P
下一篇,讓我們繼續(xù)討論,如何借助Lazy Loading,在用EF Core的Inheritance功能的時(shí)候,繼續(xù)保持?jǐn)?shù)據(jù)表的清潔(不需要有冗余的字段)。敬請(qǐng)期待噢。 :-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ū)新聞,深度好文,歡迎訪問(wèn)公眾號(hào)文章匯總 http://www.csharpkit.com


總結(jié)

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

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