2013-12-16 264 views
1

我到處讀到從數據庫獲取新數據的正確方法是創建DbContext的新實例,並刪除現有的數據。雖然這可能在某些情況下是廢話,但我發現很難在更復雜的情景中實現這一點。有問題的應用程序類型是客戶端應用程序,只要顯示窗體/視圖,上下文就處於這種狀態。例如,假設我們正在添加一些類型A(這是主數據)的數據,並且類型A的特定實例引用了類型B和C(這是引用的數據)的對象。這意味着在屏幕上我可以加載A的列表,B的列表和C的列表。讓我們說B的列表已經在網絡上收到了一些變化,我想加載。我怎樣才能刷新B的列表,而不需要從數據庫(獲取所有三個列表,因爲如果我摧毀的背景下,這是我需要做什麼?DbContext緩存數據

obvoius mehod會事端喜歡

​​

我們沒有...

回答

0

在測試過程中,我發現從數據庫刷新數據(添加,更新和刪除)的唯一方法是使用ObjectContext的ObjectSet並將MergeOption設置爲OverwriteChanges(DbContext不公開此類方法)。

var objectContext = ((IObjectContextAdapter)Context).ObjectContext; 
ObjectSet<T> set = objectContext.CreateObjectSet<T>(); 
set.MergeOption = MergeOption.OverwriteChanges; 
var list = set.ToList(); 
4

你正在尋找的方法是here

Context.Set<B>().AsNoTracking().ToList(); 
+0

我沒有看到AsNoTracking如何在上述場景中使用,但也許我沒有看到什麼東西。如果我沒有跟蹤某件事情,那就意味着它沒有依附於上下文。如果它沒有附加到上下文,那麼它不能被更新。在上述情況下,我正在更新數據。那麼,你是如何確切地意味着這個工作的? – Goran

+0

@Goran你可以附加沒有被跟蹤的實體。您甚至可以將實體附加到實現它的實體的不同上下文中。 – qujck

+0

我知道我可以附加它。如果我接近它,那麼它被緩存。我將如何更新它,因爲現在正在跟蹤它,這與您所建議的狀態相反? – Goran

1

如果你正在尋找更新實體的現有列表從DB可能是更新後的值,你可以使用ObjectContextRefresh方法:

// what to refresh 
// this will refresh all cached instances of B entities 
var entitiesToRefresh = dbContext.Set<B>().Local; 

var objectContext = ((IObjectContextAdapter)dbContext).ObjectContext; 
objectContext.Refresh(RefreshMode.StoreWins, entitiesToRefresh); 

注意這不會從DB加載新的實體,如果有應的項目添加到列表中 - 你需要重新查詢那些項目。

+0

這是哪種方法我在使用單個實體列表時使用。但是,我沒有看到一種方法可以更新對象圖的數據?想象一下,在A是發票的情況下,B是InvoiceItem,C是產品,D是客戶等。如果發票123在網絡上發生更改,並且我正在通過發票進行導航(後退/前進),那麼當我導航到發票123時,如何加載發票123的新數據? – Goran

+0

從你想刷新的對象圖建立一個實體列表 – Moho

+0

因此,可以說我點擊後退按鈕來加載以前的記錄。在這一點上,我不知道以前的記錄是什麼,所以我需要從數據庫中獲取它(這會得到添加的項目)。然後我會檢查上下文是否緩存。如果是的話,那麼我會做三個列表,每個列表爲父實體,子代和孫代,然後發送給Refresh。這是你的建議嗎?我需要確保在進行一些測試之前我已經明白了。 – Goran