【问题标题】:Persisting EF changes with constantly refreshed repository in WPF MVVM在 WPF MVVM 中使用不断刷新的存储库来持久化 EF 更改
【发布时间】:2015-10-27 09:46:06
【问题描述】:

使用 MVVM 处理 WPF 应用程序并由实体框架提供支持。出于可用性目的,我们非常希望允许用户在这个应用程序中使用多窗口。但是,这有可能导致 EF 出现问题。如果我们坚持为每个 ViewModel 创建一个 Repository 副本的通常建议,并且有人打开同一个 ViewModel 的多个窗口,则可能会导致“IEntityChangeTracker 的多个实例”错误。

我们没有使用有其自身问题的 Singleton,而是通过将 Refresh 方法放在获取新数据上下文的存储库上来解决这个问题。然后我们在整个商店里做这样的事情:

using (IRepository r = Rep.Refresh())
{
    r.Update(CurrentCampaign);
    r.SaveChanges();
}

这大部分都很好。但是,它会导致维护状态的问题。如果在用户使用对象时刷新上下文,他们的更改将会丢失。

我可以看到两种解决方法,它们都有自己的缺点。

  • 我们不断调用 SaveChanges。这有可能通过不断的数据库调用减慢应用程序的速度。此外,有时我们不想存储不完整的对象。
  • 我们在加载时将 EF 对象复制到内存中,让用户使用这些对象,然后添加一个“保存”按钮,将所有对象复制回 EF 对象并保存。我们可以使用自动映射器来做到这一点,但似乎仍然没有必要。

还有其他方法吗?

【问题讨论】:

  • 我在当前项目中通过编写自己的 Repository 类并使用第二种方法解决了这个问题。任何需要更改 repo 的东西都必须首先获取一个 Context 对象,该对象将一个互斥锁锁定在 ctor 中并在 Dispose() 中将其解锁。这是我个人更喜欢 NHibernate-and-Fluent 组合的原因之一,它对这类东西有更好的开箱即用支持
  • 听起来您在 ViewModel 中使用了 DAO 对象,这是您永远不应该这样做的。

标签: c# wpf entity-framework mvvm


【解决方案1】:

我相信将用于访问实体框架的存储库作为单例可能并不总是错误的。

如果您有一个场景,即您有一个客户端存储库,即作为客户端应用程序可执行文件一部分的存储库,即由一个客户端使用,那么单例可能没问题。当然,我不会在服务器端使用单例。

我在复数网站上的“MVVM”课程上向 Brian Noyes(Microsoft MVP)提出了类似的问题。

我问:“处理视图模型中使用的客户端服务的正确方法是什么?”

在他的回复中,他写道:“......无论如何,我的大多数客户服务都是单例,并且为应用程序的生命而存在。”

此外,拥有单例并不妨碍您编写单元测试,只要您有单例的接口即可。

如果您使用依赖注入框架(请参阅 Marks 注释),这对自己来说是个好主意,更改为单例实例化只需对相应类的注入容器的设置进行微小更改即可。

【讨论】:

  • 如果您正在使用依赖注入(并且您应该使用),那么您可以按照您喜欢的任何方式确定它们的范围,甚至在需要时更改它。对于我自己的存储库,我为离线实用程序使用单例范围,为 WPF 应用程序执行表单范围,为 Web 应用程序执行每个请求范围……所有这些都使用相同的 ORM 代码。
  • @Mark,比你,我在回复中添加了使用 DI 框架的提示
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-29
  • 1970-01-01
  • 2015-09-12
相关资源
最近更新 更多