2013-04-12 146 views
2

說在EF 4中對分離實體進行了更改。如果我們想在重新連接實體時保存這些更改,是否可以使用ApplyCurrentValues查詢數據庫以獲取原始實體?我不這麼認爲,但我希望有人確認。實體框架 - 保存對分離實體所做的更改

using (var ctx = new BAEntities()) 
{ 
var firstCust = (from c in ctx.Contacts select c).First(); 
Console.WriteLine(firstCust.FirstName); 
ctx.Contacts.Detach(firstCust); 

firstCust.FirstName = "Modified Value"; 
ctx.Contacts.Attach(firstCust); 
ctx.ApplyCurrentValues("Contacts", firstCust);//Does not work 

//ctx.ObjectStateManager.ChangeObjectState(firstCust, EntityState.Modified); //Works with that line 
      ctx.SaveChanges(); 
} 

謝謝

回答

5

我可以證實你的猜測。它不以這種方式工作。

當您使用實體作爲參數調用Attach時,EF將該實體添加到狀態爲Unchanged的上下文中。基本上,您通過Attach告訴EF,實體當時具有的所有屬性值都代表數據庫中的當前值。

ApplyCurrentValues是一種「自動映射器」,它只是將您傳入的對象的屬性值複製到具有相同密鑰的附加實體中,即ApplyCurrentValues。此副本基於屬性名稱發生。

如果附屬實體的屬性值與您傳入的對象的屬性值不同ApplyCurrentValues EF將屬性標記爲Modified。如果不是狀態爲Unchanged。很明顯,在你的程序中,所有的財產狀態都會保持不變,沒有任何東西會被寫入數據庫。

從理論上講,你可以做瘋狂的事情,使其工作,如:

firstCust.FirstName = "Modified Value"; 
var dummyCust = new Contact { FirstName = "UnlikelyNameThatWillNeverOccur" }; 
ctx.Contacts.Attach(dummyCust); 
ctx.ApplyCurrentValues("Contacts", firstCust); 

這裏FirstName屬性將被標記爲Modified。但是您必須爲每個屬性執行此操作,結果與將整個實體的狀態設置爲Modified的結果相同,如同在註釋代碼行中所做的那樣。

您可以通過方式單一屬性設置爲Modified

ctx.Contacts.Attach(firstCust); 
ctx.ObjectStateManager.GetObjectStateEntry(firstCust) 
    .SetModifiedProperty("FirstName"); 

這將發送一個UPDATE語句僅設置FirstName列值的數據庫(而整個實體的狀態設置爲Modified將創建UPDATE語句,將所有列值設置爲當前屬性值)。