【发布时间】:2016-02-14 13:26:56
【问题描述】:
我对关于数据访问的 MVVM 应用程序(以前的 WinRT,现在针对 UWP)的体系结构感到非常困惑。我很不确定如何在 UI 中传播更改以及在何处访问数据层。
这是基本架构:
- 模型层: 包含只有自动属性的模型(没有引用其他模型的导航属性,只有 ID;所以它们基本上只是数据库的表示)。他们没有实现 INotifyPropertyChanged。
- 数据访问层: 使用 sqlite-net 将模型存储在数据库中的存储库。它公开了基本的 CRUD 操作。它从模型层返回并接受模型。
-
视图模型:
- 模型的视图模型:它们环绕模型并公开属性。有时我会将控件的内容(例如 TextBoxes)双向绑定到属性。然后,setter 访问数据层以保持此更改。
- 用于视图的 PageViewModels:它们包含来自上方的 ViewModels 和命令。许多命令已经变得很长,因为它们执行数据访问、执行特定领域的逻辑和更新 PageViewModels 属性。
- 视图(页面):它们绑定到 PageViewModel 并通过 DataTemplate 绑定到模型的 ViewModel。有时有双向数据绑定,有时我使用命令。
我现在对这个架构有几个问题:
问题 1: 一个模型可以在多个宫殿的屏幕上显示。例如,一个主从视图显示一个类型的所有可用实体的列表。用户可以选择其中之一,其内容将显示在详细视图中。如果用户现在更改详细视图中的属性(例如模型名称),则更改应立即反映在主列表中。这样做的最佳方法是什么?
- 有模型的一个 ViewModel?我认为这没有多大意义,因为主列表只需要很少的逻辑,而详细视图则需要更多。
- 让 模型实现 INotifyPropertyChanged 从而将更改传播到 ViewModel?我遇到的问题是,数据层目前不保证它为一个模型 id 上的两次读取操作返回的对象是相同的——它们只包含从数据库读取的数据,并且在读取它们时是新创建的(我认为这就是 sqlite-net 的工作方式)。我也不确定如何避免由于 ViewModel 中的所有 PropertyChanged 事件订阅而发生内存泄漏。我应该实现 IDisposable 并让 PageViewModel 调用其子级的 Dispose() 方法吗?
- 我目前在我的数据访问层上有一个DataChanged 事件。每当发生创建、更新或删除操作时都会调用它。可以同时显示的每个 ViewModel 都会监听此事件,检查更改后的模型是否是其 ViewModel 的模型,然后更新自己的属性。我又遇到了内存泄漏的问题,这变得很慢,因为太多的 ViewModel 必须检查更改是否真的适合他们。
- 另一种方式?
问题 2: 我也不确定我访问数据的地方是否真的选择得很好。 PageViewModels 变得非常复杂,基本上可以做所有事情。所有 ViewModel 都需要了解我的架构中的数据层。
我一直在考虑使用 sqlite-net 来取消数据访问并改用 Entity Framework 7。 这会解决上述问题吗,即当我使用相同的上下文?我还认为它会简化 ViewModel,因为我很少需要读取操作,因为这是通过导航属性完成的。
我也一直想知道在 MVVM 应用程序中使用两种方式的数据绑定是否是个好主意,因为它需要属性设置器调用数据访问层来持久化更改。只做单向绑定并通过命令持久化所有更改会更好吗?
如果有人能对我的架构发表评论并提出改进建议或指出关于 MVVM 架构的优秀文章,我将非常高兴。
【问题讨论】:
标签: c# entity-framework mvvm architecture