2010-03-03 60 views
2

我有一個Visual Studio 2010生成的POCO類集合(剛剛從DB架構生成的POCO模板)。對於給定的用例,我讓用戶加載一個實體(一個CRM聯繫人)並採取行動 - 添加電話號碼(本身是一個與外鍵相關的獨立實體)和地址(也是一個單獨的實體)等。回發我將修改後的實體存儲在ViewState中(我不想立即將更改保存到數據庫中)。當用戶點擊保存按鈕時會出現問題。主CRM聯繫人將被保存正常(檢測並保存任何更改),但沒有任何相關屬性會被保存 - 無論是新添加項還是修改後的EF都會忽略它。實體框架中的POCO與快照更改檢測

如何強制Entity Framework檢測到我的相關屬性發生了更改?我使用這個救我的主要聯繫人:

//contact is an instance of CRMContact retrieved from ViewState 
if (contact.Id == 0) { 
    CRMEntities.CRMContacts.AddObject(contact); 
} else { 
    CRMContact orig = CRMEntities.CRMContacts.Where(c => c.Id == contact.Id).FirstOrDefault(); 
    CRMEntities.CRMContacts.ApplyCurrentValues(contact); 
} 

CRMEntities.SaveChanges(SaveOptions.DetectChangesBeforeSave | SaveOptions.AcceptAllChangesAfterSave); 

也能正常工作聯繫人實體,但不是我相關的人。我需要添加什麼來添加和/或更新電話號碼和電子郵件?

請注意,我不想使用基於代理的更改跟蹤。

謝謝

回答

2

經過大量的試驗和錯誤,我設法把一些有效的東西放在一起。請注意,我不知道這是否是正確的方式。這是來自項目不同部分的代碼。 IAHeader是一個主要實體,IAAttachmentIAComment都通過外鍵鏈接到標題:

public static void Save(IAHeader head) { 
    IAHeader orig = new IAHeader(); 
    if (head.Id == 0) { 
     IAData.Entities.IAHeaders.AddObject(head); 
    } else { 
     orig = IAData.Entities.IAHeaders.Where(h => h.Id == head.Id).FirstOrDefault(); 
     IAData.Entities.IAHeaders.ApplyCurrentValues(head); 

     foreach (IAComment comm in head.Comments.ToList()) { 
      if (comm.Id == 0) { 
       comm.IAHeader = null; //disassociate this entity from the parent, otherwise parent will be re-added 
       comm.IAId = head.Id; 
       IAData.Entities.IAComments.AddObject(comm); 
      } else { 
       IAComment origComm = orig.Comments.Where(c => c.Id == comm.Id).First(); 
       IAData.Entities.IAComments.ApplyCurrentValues(comm); 
      } 
     } 

     foreach (IAAttachment att in head.Attachments.ToList()) { 
      if (att.Id == 0) { 
       att.IAHeader = null; //disassociate this entity from the parent, otherwise parent will be re-added 
       att.IAId = head.Id; 
       IAData.Entities.IAAttachments.AddObject(att); 
      } else { 
       IAAttachment origAtt = orig.Attachments.Where(a => a.Id == att.Id).First(); 
       IAData.Entities.IAAttachments.ApplyCurrentValues(att); 
      } 
     } 
    } 
    IAData.Entities.SaveChanges(SaveOptions.DetectChangesBeforeSave | SaveOptions.AcceptAllChangesAfterSave); 
} 

很多可以改進,很明顯,但是這是我想出了到目前爲止,對我的工作場景。大部分讓我困擾的重要部分是不得不將我的導航屬性從我的主要實體中解除關聯,否則我會得到「實體鍵已經存在」的錯誤,或者主實體會被保存兩次。

0

我看不到您更改了任何相關值。該docs for ObjectContext.ApplyCurrentValues說:

複製標量值從提供的對象爲在ObjectContext的對象具有相同的密鑰

(着重號。)

既然你做了沒有其他變化,我會說沒有什麼發現。

+0

我試着循環遍歷我的導航屬性,並在每個單獨的'AddObject'或'ApplyCurrentValues'上執行操作,但是,在這個代碼中,我得到了'保存更改時'具有相同鍵的項目已經被添加'異常,所以我想我的問題是如何正確**在這種情況下創建一個「保存」功能 – 2010-03-03 18:53:32

+0

並且對應用程序各個位置的導航屬性進行了更改 - 我發佈的內容只是我的「保存」方法的一部分 - 毫無疑問,需要檢測的變化 – 2010-03-03 18:56:41

+0

然後,您應該顯示該代碼。我能看到的只是迄今爲止發佈的內容;我無法用我從未見過的代碼診斷問題。嘗試將問題簡化爲簡單的測試用例。 – 2010-03-03 19:37:37