实体框架 4.1 DbSet 重新加载

Posted

技术标签:

【中文标题】实体框架 4.1 DbSet 重新加载【英文标题】:Entity Framework 4.1 DbSet Reload 【发布时间】:2011-08-13 13:44:27 【问题描述】:

我正在使用 DbContext 场景的单个实例在 WPF 应用程序中本地隐藏整个数据库副本。我听说这是不好的做法,但我的数据库很小,并且在应用程序运行时我需要在本地获得完整的副本。

IQueryableLoad() 的扩展方法让我可以预加载DbSet<> 的元素,这样我就可以将事物绑定到DbSet<> 的Local 属性。数据库中的数据变化很快,所以我想SaveChanges() 并重新加载一切,甚至是已经跟踪的对象。再次调用Load() 方法不会更新已跟踪但未标记为已更改的项目。

DbSet<> 中重新加载预加载项的首选方法是什么?在我的脑海中,我只能想到调用SaveChanges(),然后遍历所有条目并将跟踪值和原始值设置为数据库中的当前值,然后Load() 可能已添加的任何新对象。在我的场景中,不可能删除对象,但从长远来看,我可能必须支持项目删除。这似乎不对,应该有一种方法可以删除所有内容并重新加载。似乎放弃我的上下文并重新开始更容易,但是 WPF 中的所有元素都已经绑定到Local´ObservableCollection<>,这只会弄乱界面。

【问题讨论】:

【参考方案1】:

这不是您应该使用DbContext 的方式,因此几乎不可能重新加载数据。长时间保持单一上下文是incorrect usage。该链接还将回答您跟踪的实体未更新的原因。

您可以通过在DbEntityEntry 上调用Reload 来选择性地重新加载单个实体:

context.Entry(entity).Reload();

您还可以恢复为ObjectContext 并将ObjectQueryMergeOption.OverrideChanges 一起使用,或者将RefreshRefreshMode.StoreWins 一起用于实体集合。

所有这些方法都存在一些问题:

如果记录在数据库中被删除,它不会从上下文中删除。 关系的变化并不总是被刷新。

获取新数据的唯一正确方法是Dispose 上下文,创建一个新的并从头开始加载所有内容 - 无论如何你都在这样做。

【讨论】:

感谢您的回复,但我有点迷茫,因为我已经读到在我的场景中首选完全相反的情况。我会回顾这些主题,然后回来。 我不会在关系中发生任何变化,也不会在数据库中删除。我将在今天晚些时候开始另一个问题,并尝试解释为什么我不能拥有一个短暂的 DbContext。我真的希望你能提供一些有价值的意见。【参考方案2】:

在 Entity Framework 4.1 中,WPF 数据绑定的建议已更改为使用 .Local 和持久 DbContext。

http://blogs.msdn.com/b/efdesign/archive/2010/09/08/data-binding-with-dbcontext.aspx

当然,您可以在需要时将其丢弃,但如果您这样做,可能会对 UI 产生负面影响。

这是另一种方法,但我不确定它是否考虑了 EF4.1 的功能:

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

【讨论】:

非常感谢,我对整个 .Local 的事情感到非常困惑。每个人和他们的狗都告诉我不要出于任何原因使用单个 DbContext,但它清楚地为长期绑定提供了这个 .Local 属性。 @Gleno 我完全同意你的看法,恕我直言,大多数人将它用于上下文短暂的 ASP,但对于桌面应用程序,重新加载您输入新表单的所有内容只是无稽之谈,特别是如果信息通过各种形式的应用共享。【参考方案3】:

DbContexts 应该存在很短的时间, 在保存更改后考虑处理它并从头开始重新加载。 有 2 组对象.. 一组来自 db,另一组用于绑定。

【讨论】:

我真的不能这样做,因为那样我会在进度中丢失 UI 状态。我真的希望我能拥有一个短暂的 DbContext,但我看不出在我的场景中它是如何实现的。【参考方案4】:

请使用 using() 进行 CRUD。它会自动重新加载更新的数据。

using (myDbContext context = new myDbContext())



最好的问候, 提丁乌

【讨论】:

以上是关于实体框架 4.1 DbSet 重新加载的主要内容,如果未能解决你的问题,请参考以下文章

实体框架 CTP5 重新加载相关实体

如何使用代码优先实体框架在 ASP.Net MVC3 中重新加载多对多导航属性

实体框架6、加载实体async/await

实体框架和 DbSet

在实体框架中,DbSet.Local 保持不同步

实体框架和DbSet