2013-12-16 269 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