2013-12-12 34 views
2

我正在使用實體框架5.0和SQLite數據庫。我有一個場景,我對數據庫記錄進行了修改,然後使用同一個表的實體對象的新實例來讀取相同的記錄,但是我得到了舊的值。在調試的時候,如果我去我的數據庫工具並查看記錄,這些變化就在那裏,但是EF並沒有選擇它們。它會在晚些時候拿起它們,但我無法確定它是什麼時候。實體框架在SaveChanges獲取舊值後讀取

以下是代碼片段。首先,我執行使用更新的SaveChanges():

tblTest efTestTbl = context.tblTests.Find(recID); 
context.tblTests.Attach(efTestTbl); 
efTestTbl.Value1 = "newValue"; // This changed it from "oldValue" :-) 
int changedRecs = context.SaveChanges(); 

這上面的代碼似乎總是工作並保存更改數據庫。 changedRecs最終等於1.我可以在代碼中的這一點之後休息,並使用我的數據庫工具查看數據庫中的值,並且該列將等於「newValue」。

現在,如果我執行下面的讀,用不同的表對象上一次更新後直接,但相同的實例的上下文對象:

tblTest efTestTbl = context.tblTests.Find(recID); 

在efTestTbl.Value1的價值將等於「屬性oldValue」 。我看到一些關於EF沒有緩存任何東西的評論,但我不能相信這是真的。在另一個論壇上,我看到一場談話談論關於ObjectQuery的MergeOption,緩存被稱爲「身份解析」。這是內容豐富的,但沒有幫助我,因爲我沒有使用查詢和「ExecuteNonQuery()」方法。

我的方案需要我寫出一個更改,然後從數據庫讀取並記錄更改作爲驗證步驟。

任何幫助,你可以給我找到一種方法來刷新緩存將不勝感激。

+0

在代碼中使用相同的上下文實例嗎? –

回答

1

根據上下文中發生的情況,您嘗試加載的對象可能已經存在於其他上下文中。

這就是我之前解決這個問題的方法;

public static class ZarettoContextExtensionClass 
{ 
    public static tblTest Reload(this tblTest item, DbContext c) 
    { 
     c.Configuration.AutoDetectChangesEnabled = false; 
     c.Entry(item).Reload(); 
     c.Configuration.AutoDetectChangesEnabled = true; 
     return item; 
    } 
} 

那麼很明顯,你會怎麼做:

efTestTbl.Reload(context) 
+0

你不是這個意思:public static tblTest Reload(this tblTest item,DbContext c)?? –

+0

@RobertAchmann是的,編輯 –

0

如果使用

tblTest efTestTbl = context.tblTests.FirstOrDefault(t => t.Id == recID); 

,而不是

tblTest efTestTbl = context.tblTests.Find(recID); 

你可以肯定的是EF會查詢數據庫,你會得到持久的數據。

使用Find()方法EF將首先檢查對象是否已經在您的數據庫上下文中,然後才決定是否會查詢數據庫。

這並不回答問題,爲什麼你會得到舊的數據,但應該解決你的問題。

我只是想知道爲什麼你在已經連接的實體efTestTbl上使用.Attach()方法? 在我看來,你分離()它在某些時候,執行沒有跟蹤的變化,並附有不正確的值(不同於數據庫),這是後來幸運的巧合保存。

你還使用AutoDetectChanges嗎?