我对我的MVVM应用程序(以前称为WinRT,现在面向UWP)的数据访问架构感到困惑。我不太确定如何在UI中传播更改以及在何处访问数据层。
这是基本架构:
我现在有这个架构的几个问题:
问题1:一个模型可以在几个宫殿的屏幕上显示出来。例如,主 - 详细视图,显示类型的所有可用实体的列表。用户可以选择其中一个,其内容显示在详细视图中。如果用户现在在详细视图中更改属性(例如模型的名称),则应立即在主列表中反映更改。这样做的最佳方式是什么?
问题2:我也不确定我访问数据的地方是否真的很好。 PageViewModels变得非常复杂,基本上做了一切。并且所有ViewModel都需要使用我的架构了解数据层。
我一直在考虑使用sqlite-net和使用Entity Framework 7来废弃数据访问。这会解决上面的问题,即当我使用时,它是否保证了一个模型的对象标识相同的背景?我还认为它会简化ViewModel,因为我很少需要读取操作,因为这是通过导航属性完成的。
我一直想知道在MVVM应用程序中是否有两路数据绑定是好主意,因为它需要属性设置器调用数据访问层来保持更改。最好只进行单向绑定并通过命令保留所有更改吗?
如果有人可以对我的架构进行评论并提出改进建议或指向关注我的问题的MVVM架构的好文章,我会非常高兴。
答案 0 :(得分:3)
- 为模型设置一个ViewModel?我认为这没有多大意义,因为主列表只需要非常少的逻辑,而且详细信息视图更多。
醇>
ViewModel不依赖于模型。 ViewModel使用该模型来满足视图的需求。 ViewModel是视图的单一联系点,因此viewmodel必须提供视图需求。所以它可以是单个模型/多个模型。但是您可以将单个ViewModel分解为多个子ViewModel,以使逻辑更容易。它的详细信息窗格可以分为具有自己的视图模型的用户控件。您的母版页将只有一个将托管此控件的窗口,而MasterViewmodel会将职责推送到子ViewModel。
- 让模型实现INotifyPropertyChanged,从而将更改传播到ViewModels?我对此有的问题是 数据层目前不保证它返回的对象 对于一个型号id上的两个读取操作是相同的 - 它们只是 包含从数据库读取的数据,并在以后新创建 他们被阅读(我认为这是sqlite-net的工作方式)。我也没有 确实如何避免因为所有问题而发生内存泄漏 来自ViewModels的PropertyChanged事件订阅。我是不是该 实现IDisposable并让PageViewModel调用它的子节点 Dispose()方法?
醇>
危险不是使用INotifyPropertyChanged
,而是正确地说了它的描述和取消订阅。无论何时需要订阅任何活动 - 不仅INotifyPropertyChanged
您需要使用IDisposable
取消订阅自己及其子ViewModels。我不清楚您描述的数据层,但如果它发布属性更改事件进行任何修改我没有看到使用INotifyPropertyChanged
的任何问题。
3.我目前在我的数据访问层上有一个DataChanged事件。只要发生创建,更新或删除操作,就会调用它。每 可以同时显示的ViewModel侦听此事件, 检查更改的模型是否是ViewModel for和 然后更新自己的属性。我又有了问题 内存泄漏,这变得很慢,因为太多的ViewModel必须这样做 检查改变是否真的适合他们。
如前所述,如果您正确处理所有模型的订阅/取消订阅,则无需担心INotifyPropertyChanged的性能问题。但是,可能会增加问题的是您为数据库请求数据的调用次数。您是否考虑过使用Async ...等待数据访问层,该层不会阻止任何更新发生的UI。即使数据更新很慢,也不会被数据调用阻止的反应式UI是更好的选择。
因此,尝试添加通过DAL层抽象的数据访问服务,并提供访问数据的异步方法。另请查看Mediator Pattern。这可能会有所帮助。
我也不确定我访问数据的地方是否真的很好 选择。 PageViewModels变得非常复杂 基本上做的一切。并且所有ViewModel都需要知识 我的架构的数据层。
我看到的两个主要问题,
我一直在考虑使用sqlite-net和使用来废弃数据访问 相反,实体框架7。
在没有确凿证据的情况下,不要尝试用EF替换sqlite-net。在尝试进行如此大的更改之前,您需要在应用中衡量性能。如果问题出在您的代码而不是您正在使用的组件中,该怎么办?首先尝试解决上述问题,然后通过接口隔离DAL层,并在需要时替换它。
我也一直想知道是否有两路数据绑定是好的 完全在MVVM应用程序中的想法,因为它需要属性设置器 调用数据访问层以保留更改。是不是更好 只执行单向绑定并通过命令保留所有更改?
如果您每次更改字段/每次按键时都直接调用数据库,那么就会出现问题。然后,您应该拥有数据模型的副本,并仅在单击保存按钮时保留更改。