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