2012-04-22 52 views
0

在我的編輯控制器操作中,我發佈要更新的對象。查詢DB加載我的對象的屬性之一,它不應該

[HttpPost] 
public virtual ActionResult Edit(Case myCase){ 
     var currentDocuments = db.CaseDocuments.Where(p => p.idCase == myCase.idCase); 

      foreach (CaseDocument docInDB in currentDocuments) 
      { 
       var deleteDoc = true; 

       foreach (CaseDocument docNew in myCase.CaseDocuments) 
       { 
        if (docNew.idDocument == docInDB.idDocument) 
         deleteDoc = false; 
       } 
       if (deleteDoc) 
        db.CaseDocuments.Remove(docInDB); 
      } 

      foreach (CaseDocument pc in myCase.CaseDocuments) 
      { 
       if (pc.idDocument == 0) 
        db.CaseDocuments.Add(pc); 
       else 
        db.Entry(pc).State = EntityState.Modified;  
      } 

      *** **db.Entry(myCase).State = EntityState.Modified;** //THIS LINE 
      db.SaveChanges(); 
} 

Case模型具有Documents的集合,並且它們與例模型一起發佈。

一旦我進入的動作,我可以算的集合中的文檔數量,並讓說,有3

然後,爲了看我是否需要從數據庫中刪除的文件(如用戶刪除一個從UI),我需要從數據庫中獲取該案例的文檔以這樣的方式

var currentDocuments = db.CaseDocuments.Where(p => p.idCase == myCase.idCase); 

在這裏開始了奇怪的事情:一旦我executa這份聲明中,myCase.Documents裝有什麼在數據庫(可以說有4)!所以,我無法比較2個集合(檢測文檔是否被刪除並從db中刪除)。

我需要的是在我的案例模型的編輯動作期間,我需要創建/更新/修改其文檔。 我需要從其他角度看這個嗎?我在做什麼是錯的?

編輯: 的意見後,我意識到,我打上myCase爲修改了行,在開始時,我想,這是對這種行爲的原因。

現在,移動該行只是db.SaveChanges(),固定的這個問題之前,但在db.Entry(myCase).State = EntityState.Modified;說:「已經有與ObjectStateManager相同的密鑰的對象。

什麼我在這裏做錯了嗎?這段代碼看起來不好!

+0

顯示你的動作的整個身體。只有當您以前將案例附加到用於檢索當前文檔的上下文時,纔會加載您的案例文檔。 – 2012-04-22 18:15:02

+0

@LadislavMrnka,它是......我仍在測試不同的方法,但我並不真正知道自己在做什麼。 – Romias 2012-04-22 19:19:23

回答

1

試試這樣說:

[HttpPost] 
public virtual ActionResult Edit(Case myCase){ 
    var currentDocumentIds = db.CaseDocuments 
           .Where(p => p.idCase == myCase.idCase) 
           .Select(p => p.idDocument); 

    foreach (int idInDb in currentDocumentsIds.Where(i => !myCase.CaseDocuments 
                    .Any(ci => ci.idDocumnet == i)) 
    { 
     var docToDelete = new CaseDocument { idDocument = idInDb }; 
     db.CaseDocuments.Remove(docToDelete); 
    } 

    foreach (CaseDocument pc in myCase.CaseDocuments) 
    { 
     if (pc.idDocument == 0) 
      db.CaseDocuments.Add(pc); 
     else 
      db.Entry(pc).State = EntityState.Modified;  
    } 

    db.Entry(myCase).State = EntityState.Modified; 
    db.SaveChanges(); 
} 

編輯:此代碼和代碼之間的區別是它的方式是如何使用現有的文件。它不加載它們 - 它只加載它們的ID。這樣你就可以節省數據庫中的一些數據傳輸,但它也可以幫助你避免這種異常。當您從數據庫中加載文件你擁有了它已經連接的情況下,但如果你嘗試調用此:

db.Entry(pc).State = EntityState.Modified; 

你會嘗試連接該文件的另一個實例使用相同的密鑰上下文。這是不允許的 - 上下文可以只附加一個具有唯一鍵的實例。

+0

謝謝!但是,你能解釋一下,你以這種方式做了什麼(以及爲什麼)?我的意思是,我可以嘗試,它會工作,但我真的需要了解它的「哲學」。 – Romias 2012-04-23 12:39:28

+0

我加了一些解釋。試試代碼,我們會看看它是否能解決你的問題。 – 2012-04-23 13:39:52

+0

謝謝,這是工作正常!點了解! – Romias 2012-04-23 17:38:43

相關問題