MVVM中的ObservableCollection和Repository模式 - 如何关联它们,以及“Update”方法的案例

时间:2013-10-16 14:02:18

标签: wpf mvvm repository-pattern observablecollection

我的桌面WPF应用程序有一个存储库(类型为Person),它位于Model层中,由一个ViewModel调用,该属性具有PersonList属性,可以数据绑定到{{1} }。

当我打开我的应用程序时,默认显示该列表。在初始化期间,以下代码适用:

DataGrid

我的疑虑是基于一些难以理解如何实施"保存/更新"方法(一个或多个)。

关于存储库模式的每个文本都告诉&#34;存储库的行为应该像[entities |]的集合域对象]&#34;。因此,最合乎逻辑的是将存储库本身数据绑定到public class PersonScreenViewModel : ViewModelBase { PersonRepository _person_repository; public ObservableCollection<Person> PersonList { get; set; } public PersonScreenViewModel() { _repositorio_pacientes = new RepositorioPacientes(); PersonList = new ObservableCollection<Person>(_person_repository.GetAll()); } // ... /// } 。如果我创建了一个继承自DataGrid并实现存储库逻辑的类,那么就可以完成。目前,我所做的是使用ObservableCollection获取存储库项目的副本,并在该副本中工作,在完成更改后必须提交回来。

  

具体来说,我的工作流程涉及在DataGrid中选择一行,更改所选对象的某些属性以及提交这些更改,期望使用新属性值保留相同的对象。

通常情况下,如果你在一个集合中取一个对象并对其进行修改,你就不需要更新&#34;什么,因为你已经改变了对象本身。

问题是:&#34;我如何将数据绑定到存储库本身?回购是否应继承自_repo.GetAll()?它应该如何完成?我推理的某些部分有缺陷吗?&#34;

重要的是要说我的应用程序不是面向数据的,ObservableCollection类是非常基本的(POCO标记为Person,具有一些属性),我的存储库使用纯XML序列化和文件系统结构。

感谢阅读!

2 个答案:

答案 0 :(得分:2)

在我个人看来,你目前正在做的是正确的......通常很好的做法是在应用程序的各个层之间进行一些分离;模型,视图模型,视图和DataAccess(有时组合成模型)。话虽如此,它实际上取决于您的应用程序...在小型应用程序上执行此操作可能不值得,因为它增加了大量代码和时间来设置和维护。

然而,提供这种分离的主要原因(称为关注点分离)是使单元测试能够在不涉及其他层的情况下测试各个层。例如,如果我们想为视图模型编写单元测试,我们就不希望在数据库中的实际数据对象上测试它们的功能。如果我们有这种分离(通过使用接口),那么我们可以简单地模拟在这些测试期间使用的数据对象。

另一个原因,虽然在实践中不常见,但是要使整个图层“换出”而不影响其他图层中的代码。这样的示例包括更改应用程序中使用的数据库,或者可能将视图从桌面应用程序更改为Web应用程序中的Web页面。如果我们有单独的图层,那么这些更改不会影响其他图层。

因此,要直接回答您的问题,我根本不会将您的观点绑定到存储库...保持当前的分离。毕竟,将源自数据库的集合复制到视图集合属性需要多长时间?

更新&gt;&gt;&gt;

我不确定我是否完全理解你的评论中的问题。我猜你将视图模型中的PersonList属性绑定到DataGrid.ItemsSource属性以显示数据。 DataGrid中所做的任何更改都会影响PersonList中的项目。如果您要添加“保存”Button,则可以在该单击或命令处理程序中更新数据库。

如果您正在询问如何找出哪些元素已被更改,则有几种方法可以实现此目的。这里的How to get only modified Items from WPF Data Grid帖子中有一个很好的提示,但我更喜欢使用重复的集合,只是比较它们以找到更改的元素(您需要实现Equals方法才能使用此方法)。

如果这不能回答你的问题,请告诉我。

答案 1 :(得分:1)

  

“关于存储库模式的每个文本都告诉我”存储库的行为应该像[entities |]的集合域对象“。

你原来拥有的是正确的。首先, ObservableCollection与View完美配合,因为每次添加/更新/删除都会自动传播回用户界面。如果您使用存储库实现它,那么您必须调用数据库重新加载绑定到存储库的控件

  

“我如何将数据绑定到存储库本身?应该是存储库   继承自ObservableCollection?它应该如何完成?是   我推理的某些部分存在缺陷?“

  • 您不希望数据库将存储库绑定到DataGrid本身,因为您丢失缓存,并且每次用户加载用户控件时,您总是会返回数据库。
  • 您不希望将存储库继承到ObservableCollection, ObservableCollection比简单的IEnumerable 有更多的开销,因为您已经为数据库返回了一个集合。
  • 您始终不希望ObservableCollection作为您的数据集合,因为它昂贵。根据您的场景(只读数据),可以使用简单的可枚举数据。