2012-12-20 85 views
4

我們在使用DbContext/Code First的winforms應用程序內部實現實體框架,並且有關如何正確檢查/處理實體在另一個上下文中被刪除/更新的問題的以下問題。檢查實體是否被刪除

例如,我們有一些輔助表數據(例如StateCodes),用戶可以進入另一個表並根據需要添加/刪除狀態。此輔助編輯器表單利用它自己的DbContext並在用戶退出表單後保存更改。在返回到主窗體時,主要上下文不知道對數據庫所做的更改,因此我們希望重新加載實體的DbSet。不幸的是,如果我們刪除「MI」狀態代碼,它仍然存在於DbSet的Local屬性中,即使在我們調用「Load」來引入所有內容之後EntityState仍然保持不變。

完全處置主要上下文之外,以下是檢查並查看實體是否已從數據庫中刪除的最佳方法?

foreach (State state in db.States.Local) 
{ 
    DbEntityEntry entry = db.Entry(state); 
    DbPropertyValues databaseValues = entry.GetDatabaseValues(); 
    if (databaseValues == null) 
    { 
     db.States.Remove(state); 
    } 
    else 
    { 
     entry.OriginalValues.SetValues(databaseValues); 
    } 
} 

謝謝您的幫助

回答

3

你不應該保持上下文住過去的工作單位。上下文應該只在需要的時候才能存在,否則你必然會像你所觀察的那樣緩存陷阱。 (另外,上下文實際上不是沉重的地方,當你需要的時候實例化它太耗費時間/資源密集)。

如果您確實必須保持活力,您可能需要考慮將上下文傳遞給輔助表單。

鏡像從我的意見,琢磨它作爲最好的回答

+0

謝謝您的回覆。如果我理解正確,那麼下面的邏輯可能是我們最好的選擇:用戶單擊以編輯輔助數據 - 在當前上下文中調用SaveChanges - 處理當前上下文和顯示編輯器給用戶 - 返回時,重新instanstiate上下文和再次通過初始加載數據。 –

+0

@NuNnDaDdY:是的。雖然我認爲你應該在行動中創造背景,例如'buttononClick(){using(Context c = new Context()){c.Entities.Add(e); c.SaveChanges(); }}' –

+0

你能否詳細闡述一下你在創建每個動作內部的原因。我問,因爲我試圖在整個主表單上實現數據綁定,並且有許多主從關係。如果我在每個動作的內部創建一個上下文,我想我不再能夠依靠數據綁定來進行更改跟蹤了,對嗎? –

0

首先,什麼布拉德說服務。只保留特定工作單元的上下文並處理它。不這樣做只會導致頭痛。

您還可以通過使用ObjectStateManager並傳入對象或實體鍵來檢查實體的狀態。您也可以使用

public void Refresh( RefreshMode refreshMode, IEnumerable collection )

方法關閉語境。另外,您可以檢查輸入狀態。

http://msdn.microsoft.com/en-us/library/bb503718.aspx