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

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

生活随笔

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

编程问答

【转】【翻译】实体框架中的POCO支持 - 第二部分 - 复杂类型,延迟装载和显式装载...

發(fā)布時(shí)間:2023/12/19 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】【翻译】实体框架中的POCO支持 - 第二部分 - 复杂类型,延迟装载和显式装载... 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

【原文地址】POCO in the Entity Framework : Part 2 – Complex Types, Deferred Loading and Explicit Loading
【原文發(fā)表日期】 28 May 09 09:03 AM

在上星期的貼子《POCO Experience in Entity Framework》 (實(shí)體框架中的POCO體驗(yàn))中,我討論了Entity Framework 4.0中POCO支持的基本。在這個(gè)貼子里,我將討論與POCO相關(guān)的另外幾個(gè)方面。

復(fù)雜類(lèi)型(Complex Types)

POCO中的復(fù)雜類(lèi)型支持跟常規(guī)的基于EntityObject的實(shí)體中的復(fù)雜類(lèi)型支持一樣。你要做的就是將它們聲明為POCO類(lèi),然后在你的POCO實(shí)體中使用和聲明基于它們的屬性。

作為例子,這里是一個(gè)InventoryDetail復(fù)雜類(lèi)型,代表我的Product實(shí)體的一個(gè)部分:

public class {
public UnitsInStock { ; ; }
public UnitsOnOrder { ; ; }
public ReorderLevel { ; ; }
}

把我的Product類(lèi)修改成包含一個(gè)這個(gè)類(lèi)型的屬性,用來(lái)組合幾個(gè)有關(guān)庫(kù)存細(xì)節(jié)的字段:

public class {
public int ProductID { ; ; }
public string ProductName { ; ; }
public int SupplierID { ; ; }
public string QuantityPerUnit { ; ; }
public decimal UnitPrice { ; ; }
public InventoryDetail { ; ; }
public bool Discontinued { ; ; }
public Category { ; ; }
}

然后你可以做你以前對(duì)復(fù)雜類(lèi)型所能做的一切,這是一個(gè)查詢(xún)的例子:

outOfStockProducts = c in context.Products
where c.InventoryDetail.UnitsInStock == 0
c;

?

你可以看到,POCO中的復(fù)雜類(lèi)型支持用起來(lái)非常直截了當(dāng)。但在POCO中使用復(fù)雜類(lèi)型支持時(shí),你需要記住幾件事情:

  • 你必須將復(fù)雜類(lèi)型定義為類(lèi)(class),結(jié)構(gòu)體(struct)是不支持的。
  • 在你的復(fù)雜類(lèi)型類(lèi)中,你不能使用繼承。
  • 既然在討論復(fù)雜類(lèi)型,我想我要提一下另外一件事,你知道Visual Studio 2010中的實(shí)體框架設(shè)計(jì)器支持復(fù)雜類(lèi)型的聲明么?

    在Visual Studio 2008中,你只能手工將復(fù)雜類(lèi)型的聲明加到CSDL中去,但隨著Visual Studio 2010中的設(shè)計(jì)器中對(duì)復(fù)雜類(lèi)型支持的推出,這一切都成了歷史。

    更酷的是,因?yàn)閂isual Studio 2010支持多定向(Multi-Targeting),你可以在開(kāi)發(fā)針對(duì).NET Framework 3.5,使用了Entity Framework 3.5的應(yīng)用中也使用這個(gè)功能!

    延遲/懶式裝載

    在我2個(gè)星期前發(fā)表的《延遲裝載初覽》一文中,我提到了實(shí)體框架現(xiàn)在支持延遲裝載了。默認(rèn)的、代碼生成的基于EntityObject的實(shí)體類(lèi)型將提供延遲裝載,自然毫不奇怪。如果你想知道POCO對(duì)象中是否也支持延遲裝載,那么我想,你會(huì)很高興地知道,你在POCO中也能得到延遲裝載支持。

    為在POCO實(shí)體中使用延遲裝載支持,你需要做2件事情:

  • 將你想要懶式裝載的屬性聲明為virtual,這些屬性可以是任何實(shí)現(xiàn)了ICollection<T> 的集合類(lèi),或者它們可以是代表了1/0..1 關(guān)系的引用。
  • 例如,這里是更新過(guò)的Category實(shí)體類(lèi)的部分代碼,我將其改成支持延遲裝載了:

    public class
    {
    public int CategoryID { ; ; }
    public string CategoryName { ; ; }
    public string Description { ; ; }
    public byte[] Picture { ; ; }
    public virtual <> Products { ; ; }
    ...

    ???? 2.?? 在上下文中啟用延遲裝載選項(xiàng):

    context.ContextOptions.DeferredLoadingEnabled = true;

    ?

    這就行了,你現(xiàn)在就將得到POCO類(lèi)型的自動(dòng)延遲裝載,而不用做任何其他什么事情。

    那么這玩意到底是怎么工作的,底層是怎么進(jìn)行的?

    這玩意能工作的原因是因?yàn)?#xff0c;在我將集合類(lèi)型的屬性標(biāo)記為virtual后,這允許實(shí)體框架在運(yùn)行時(shí)為我的POCO類(lèi)型提供一個(gè)代理(proxy) 實(shí)例,正是這個(gè)代理實(shí)現(xiàn)了自動(dòng)的延遲裝載。該代理實(shí)例是基于一個(gè)繼承自我的POCO實(shí)體類(lèi)的類(lèi)型,所以你提供的所有功能都被保留下來(lái)了。從開(kāi)發(fā)人員的角度來(lái)看,即使延遲裝載或許是個(gè)需求,這也允許你編寫(xiě)透明持久性的代碼。

    如果你在調(diào)試器中檢查實(shí)際的實(shí)例時(shí),你會(huì)看到該實(shí)例的底層類(lèi)型與我原先聲明的類(lèi)型是不同的:

    雖然實(shí)體框架盡力以最小的摩擦提供自動(dòng)的延遲裝載,但在處理你想要添加或附加手工生成的實(shí)例時(shí),或者當(dāng)你序列化/發(fā)序列化實(shí)例時(shí),這是你需要知道的事情。

    為POCO實(shí)體手工生成代理實(shí)例

    為了允許可以添加或附加的代理實(shí)例的生成,你可以使用ObjectContext上的CreateObject工廠方法來(lái)生成實(shí)體實(shí)例:

    category = context.CreateObject<>();

    ?

    要把這個(gè)記住,在生成你想要用于實(shí)體框架的實(shí)例時(shí),要使用CreateObject

    用“變動(dòng)跟蹤代理(Change Tracking Proxies)”來(lái)提供更有效的變動(dòng)跟蹤

    到目前為止,我們討論過(guò)的標(biāo)準(zhǔn)POCO實(shí)體都依賴(lài)于基于快照(snapshot)的變動(dòng)跟蹤,即,實(shí)體框架會(huì)保管實(shí)體變動(dòng)之前的值和關(guān)系的快照,這樣,在保存(Save)時(shí),可以與當(dāng)前的值做比較。但這個(gè)比較的花銷(xiāo)是相當(dāng)大的,如果跟基于EntityObject的實(shí)體的變動(dòng)跟蹤的方式相比的話。

    還有另外一種類(lèi)型的代理,它允許你在使用POCO實(shí)體時(shí)得到比較好的變動(dòng)跟蹤性能。

    如果你熟悉IPOCO接口,你知道IEntityWithChangeTracker是要求你在類(lèi)中實(shí)現(xiàn)、來(lái)向?qū)嶓w框架提供變動(dòng)通知的接口之一。

    變動(dòng)跟蹤代理從你的POCO實(shí)體類(lèi)繼承而來(lái),在運(yùn)行時(shí)給你提供這個(gè)功能,而不要求你自己實(shí)現(xiàn)IPOCO接口。

    從許多方面講,用這種方式的話,你是魚(yú)與熊掌都兼得了:你得到了POCO類(lèi)的透明持久性,在變動(dòng)跟蹤方面你也得到了EntityObject / IPOCO 的性能。

    為了得到變動(dòng)跟蹤代理,基本的規(guī)則是,你的類(lèi)必須是公開(kāi)的,非抽象的或者非密封的(non-sealed)。你的類(lèi)對(duì)所有要持久的屬性都必須實(shí)現(xiàn)公開(kāi)的virtual getters/setters。最后,你必須將基于集合的關(guān)系導(dǎo)航屬性嚴(yán)格聲明為ICollection<T>。它們不能是具體的實(shí)現(xiàn)或者繼承自ICollection<T>的另外的接口(與延遲裝載代理有所不同)。

    這里是我的Product POCO類(lèi)的例子,它將在運(yùn)行時(shí)給我提供更有效的基于代理的變動(dòng)跟蹤:

    public class {
    public virtual int ProductID { ; ; }
    public virtual string ProductName { ; ; }
    public virtual int SupplierID { ; ; }
    public virtual string QuantityPerUnit { ; ; }
    public virtual decimal UnitPrice { ; ; }
    public virtual InventoryDetail { ; ; }
    public virtual bool Discontinued { ; ; }
    public virtual Category { ; ; }
    }

    再說(shuō)一遍,要記住,如果你要將實(shí)體加到或附加到上下文的話,你必須使用CreateObject來(lái)生成代理實(shí)例。但不依賴(lài)代理的純粹的POCO實(shí)體和基于代理的實(shí)體可以共處。你只有在涉及基于代理的實(shí)體時(shí)才需使用CreateObject。

    如果我想在同個(gè)POCO類(lèi)型中同時(shí)啟用延遲裝載和更好的變動(dòng)跟蹤,該怎么辦?

    這兩個(gè)東西不是互相排斥的,你不必在延遲裝載代理和變動(dòng)跟蹤代理間做選擇。如果你想要延遲裝載,以及有效的變動(dòng)跟蹤,你只要按照變動(dòng)跟蹤代理的規(guī)則辦,以及啟用延遲裝載選項(xiàng)。變動(dòng)跟蹤代理會(huì)給你提供延遲裝載,如果延遲裝載選項(xiàng)是啟用了的話。

    顯式裝載

    這個(gè)延遲裝載的功能確實(shí)很棒,但你們中很多人大概想要完全控制你是如何裝載相關(guān)實(shí)體的吧。你甚至?xí)x擇走純粹的POCO之路,而不訴諸于任何自動(dòng)代理生成能給你提供的功能。

    這是完全可以接受的,(在很多情形下也許是更好的方法),你可以使用顯式關(guān)系裝載,對(duì)你是如何在數(shù)據(jù)庫(kù)中查詢(xún)數(shù)據(jù)的做完全的控制。

    在POCO中做顯式裝載,有2個(gè)選項(xiàng):

    一個(gè)是使用 ObjectContext.LoadProperty ,設(shè)置你想要裝載的導(dǎo)航屬性的名稱(chēng):

    context.LoadProperty(beveragesCategory, );

    這是可行的,但你可以看出來(lái),這并不類(lèi)型安全(type safe)。如果我沒(méi)有正確的導(dǎo)航屬性的名稱(chēng)的話,我會(huì)得到一個(gè)運(yùn)行時(shí)異常。

    你們中的一些人大概更喜歡這個(gè):

    context.LoadProperty(beveragesCategory, c => c.Products);

    我可以使用lambda表達(dá)式來(lái)指定我想要顯式裝載的屬性,這提供了更好的類(lèi)型安全。

    上面是我計(jì)劃在這第二個(gè)貼子里討論的所有的內(nèi)容了。但以后還會(huì)有更多內(nèi)容,在這個(gè)系列的最后一篇里,我們將討論在處理純POCO(非代理化的)實(shí)例以及在你的對(duì)象圖和對(duì)象狀態(tài)管理器(Object State Manager)間保持一致時(shí)需要知道的幾件事情。我們也會(huì)討論你也許想要知道的SaveChanges方法的多個(gè)變種。

    與此同時(shí),請(qǐng)看一下我更新過(guò)的樣例代碼,其中包括了我們?cè)诒举N里討論過(guò)的一些東西。

    Faisal Mohamood
    Entity Framework的Program Manager

    附件: NorthwindPocoSamplePart2.zip

    推薦文章
    • 博客堂源代碼發(fā)布已經(jīng)發(fā)布于Codeplex,邀請(qǐng)您來(lái)捉臭蟲(chóng)
    • 面向?qū)ο笤O(shè)計(jì)講義
    • 如何判斷當(dāng)前瀏覽器是否是IE8?
    • ten years of msn
    • 硅脂
    • MVC模式結(jié)合Mediator模式的運(yùn)用
    • 有點(diǎn)郁悶:MSDN文檔中MidpointRounding.AwayFromZero的翻譯錯(cuò)誤
    • CodeFx 6月14日更新:14個(gè)新示例代碼
    • 作用域
    • Expression Web 3
    • [Excel Services]連接外部數(shù)據(jù)庫(kù),刷新數(shù)據(jù)的時(shí)候遇到“Data Refresh Failed ”的解決方法

    轉(zhuǎn)載于:https://www.cnblogs.com/lfzx_1227/archive/2009/05/29/1550629.html

    創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

    總結(jié)

    以上是生活随笔為你收集整理的【转】【翻译】实体框架中的POCO支持 - 第二部分 - 复杂类型,延迟装载和显式装载...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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