3

我想創建一個集成測試,從數據庫中抓取一個EF實體,將其克隆到一個分離的對象,修改它,然後將其保存並重新與原始對象進行比較。如何爲測試目的創建EF codefirst類的分離克隆?

但是,我使用AutoMapper來創建該類的克隆,但事實證明這也被跟蹤或原始對象的別名。我需要它完全脫離EF,並且能夠在我的存儲庫類以外完成此操作(即不使用任何EF分離方法)。

這樣做的原因是我的EF類包含其他類的嵌套集合,EF不處理持久化整個對象樹。因此,我的存儲庫類中的Update()方法處理此問題,我希望NUnit測試可以測試此代碼。我希望測試能夠在沒有EF跟蹤的情況下快速創建我的原始課程的副本。

+0

我覺得這是類似的東西,它是EF代碼優先實體的映射測試:http://valueinjecter.codeplex.com/wikipage?title=Automatic% 20米%20Test%20for%20EF4%20Code%20First%20Entities&referTitle = Home,儘管它不是自動映射器 – Omu 2011-04-08 17:47:50

回答

0

如果這是一個測試,你可以做任何事情,你不必綁定到像倉庫這樣的架構方法。您的存儲庫可能接收上下文作爲注入,以便您可以訪問它。還有一點是我不相信AutoMapper會創建跟蹤的實體。

製作該類副本的一種方法是使用序列化,該序列化默認只保存公共字段(Xml序列化或DataContract序列化)。序列化對象並將其反序列化回新實例。序列化將保存整個對象圖,反序列化的對象圖將被分離。請注意,這些序列化不喜歡對象圖中的循環引用(導航屬性從A到B,從B到循環)。序列化也過於激進,因此它可以更深入地遍歷圖形 - 這在許多關係中可能特別危險。

最好的方法是使用ICloneable接口並執行Clone或定義支持方法,它將執行具有所需深度的不同克隆。

Here是基於實體克隆EntityObject的另一種方法。這是艱難的代碼,尤其是Reflection.Emit的一部分。但這不會對您有所幫助,因爲代碼優先使用POCO。

6

創建包含當前的原始,或數據庫 值的DbPropertyValues Object從CurrentValues返回, OriginalValues,或GetDatabaseValues可以用來創建的 實體的克隆克隆對象。該克隆將包含來自用於創建它的DbPropertyValues對象的 屬性值。例如:

using (var context = new UnicornsContext()) 
{ 
    var unicorn = context.Unicorns.Find(1); 

    var clonedUnicorn = context.Entry(unicorn).GetDatabaseValues().ToObject(); 
} 

注意,返回的對象不是實體,不是 上下文跟蹤。返回的對象也沒有任何 關係設置爲其他對象。

克隆的對象可用於解決與數據庫併發更新相關的問題,特別是在使用涉及與特定類型的對象綁定數據的用戶界面的情況下。(有關處理樂觀併發的更多詳細信息,請參閱 第9部分。)

*從http://blogs.msdn.com/b/adonet/archive/2011/01/30/using-dbcontext-in-ef-feature-ctp5-part-5-working-with-property-values.aspx

希望它可以幫助別人

+0

嗨,感謝您的代碼,我可能在未來遇到這種情況時嘗試。 – jaffa 2011-11-17 14:31:26

+1

非常感謝這段代碼。我用它來複制/克隆EF 5實體。使用context.MyEntity.Add(clonedEntity)將實體添加到數據庫中時,只要它們作爲Ids在模型中公開(我在生成模型時包含FK-Id),它也會保留這些關係。 – LukeSolar 2013-02-06 17:22:44

+0

另外一些方法如何包含加載的相關實體將會很有用。 – 2015-04-09 09:27:10

3

所有的煩惱都一旦你使用EF 5+他們介紹AsNoTracking()方法了。下面 行返回未鏈接的實例,因此所有的背景會不知道有關該實例中的任何改變:

context.Clients.AsNoTracking().FirstOrDefault(item => item.Id == id); 

如果客戶地址一個參考,你想未鏈接它的實例太多,只需使用一個Include

context.Clients 
     .Include("Address").AsNoTracking() 
     .FirstOrDefault(item => item.Id == id); 
相關問題