2017-03-03 143 views
1

我已經創建了一個頁面asp.net MVC用於插入記錄到數據庫,我在這裏給出一個預覽按鈕來查看數據如何在客戶端看起來之前保存它。我正在使用會話將模型傳遞到預覽頁面。在預覽頁面上,我創建了一個按鈕,可以將模型保存到數據庫的會話中,但會拋出異常「IEntityChangeTracker的多個實例不能引用實體對象」。 我正在使用相同的dbContext。我嘗試了許多用戶提供的解決方案,但他們不適合我。我附上了引發異常的代碼部分。請看我做錯了什麼。創建:一個實體對象不能被IEntityChangeTracker的多個實例引用

這裏就是我節省紀錄

var model = Session[Constants.SessionVariables.ProjectModelForPreview] as Project; 
if (create != null) 
{ 
    if (model.Id == 0) 
    { 
     if (model.IsFeatured) 
     { 
      foreach (var item in dbContext.Projects.Where(p => p.IsFeatured == true)) 
      { 
       item.IsFeatured = false; 
      } 
      dbContext.SaveChanges(); 
     } 

     dbContext.Entry(model).State = EntityState.Unchanged; 
     dbContext.SaveChanges(); 
     TempData["SuccessMessage"] = "Project created successfully."; 
     return RedirectToAction("Index"); 
    } 
} 
+0

您沒有使用相同的背景下...告訴我們更多code.how你在下一個請求中獲得相同的上下文嗎? –

+0

我正在使用基礎控制器,我已經聲明瞭上下文 –

+2

因此,第一次創建記錄並將它保存在會話中時,第二次嘗試將它附加到不同的上下文中,這就是爲什麼您可能會遇到錯誤。如果我不想錯過任何你有更大的問題,請不要在會話中保存跟蹤的實體 –

回答

1

你的控制器代碼,因此你的DbContext,是每個請求實例化。所以,你的應用程序遵循這一流程:

  • 請求1實例的DbContext 1.
  • 您通過的DbContext 1中裝入實體此實體被追蹤,以及實體本身持有到的DbContext 1
  • 參考您將此實體存儲在會話中,保持舊的DbContext存活。這是有效的,因爲默認的會話狀態工作在InProc上,而不是通過序列化。
  • 請求2進來,DbContext 2得到實例化。
  • 實體從會話中檢索。
  • 您嘗試通過DbContext 2保存實體,該實體仍由DbContext 1進行跟蹤。這將引發。

現在的解決方案有多種方法:

  • 在會話中不要保存實體的。堅持下去,並在連續的請求中再次查看它們。
  • 通過手動序列化它們來保存會話中的實體。
  • 使用.AsNoTracking()加載實體。
1

讓我們忽略了原來的問題,現在,它將一旦你如果由於某種原因,你正在使用跨請求相同的上下文重構代碼

1)解決了,停下來。 (我不認爲你這樣做)。

2)不要在會話中保存跟蹤的實體* 在google上搜索以查看EF如何跟蹤更改。

3)閱讀1和2再次

*使用.AsNoTracking()或項目的實體在一個新的模型,並保存在會話

相關問題