MVVM,集合和ORM

kub*_*003 5 wpf mvvm

我试图使用MVVM和Entity Framework的MVVM设计模式来创建一个简单的应用程序.如果课程松散耦合,一切顺利,好,但如果我有...... 比如两个模型类:Customer和Address,Customer有一组Addresses.

现在,对于那些类,我需要创建两个VM类 - CustomerVM和AddressVM.CustomerVM应具有AddressVM对象的ObservableCollection.对这些VM类(包括CustomerVM和AddressVM上的所有CRUD操作)所做的每一次更改都需要反映在模型类中 - 这就是为什么我最终编写了一些代码,例如.订阅ObservableCollection的已更改事件,如果添加了新对象,则向模型添加新对象......依此类推......

怎么办?使用MVVM时这是常见的吗?我做的一切都好吗?如何减少这种简单类层次结构所需的代码量?是否有任何框架可以创建与层次结构中的其他类"表现良好"的基本VM类?如果阶级关系变得更复杂怎么办?

或者简单地说:

如何反映模型集合中vm集合中所做的更改:

CustomerVM1.AdressesVM.Add(new AddressVM{City="New York"}) 
Run Code Online (Sandbox Code Playgroud)

应该导致相当于:

Customer1.Adresses.Add(new Address{City="New York"})
Run Code Online (Sandbox Code Playgroud)

反过来也有同样的问题 - 如何反映模型中集合的更改要包含在视图模型中,但我对第一个更感兴趣,因为它有一个更实际的应用程序,vm对象可以在大多数情况下只需重新创建.

Sco*_*ock 0

您遇到的问题与我在尝试弄清楚如何使ObservableCollectionViewModel 中的 与模型中的普通旧集合保持同步时遇到的问题完全相同。AnObservableCollection很棒,因为视图可以绑定到它并在集合更改时自动更改。不幸的是,您刚刚将同步问题下移了一级。

一种选择是在任何地方使用 ObservableCollections,甚至在模型中。这不是一个非常干净的架构,因为 MVVM 不应该对模型提出任何要求。

我解决这个问题的方法是引入一个 Presenter,所以我的架构如下所示:

View -> ViewModel <-> Presenter <-> Model
Run Code Online (Sandbox Code Playgroud)

另外,我让我的 ViewModel 变得愚蠢。以下是典型的用户操作从启动到完成的过程:

  1. 用户单击“添加”按钮
  2. ViewModel 要么引发 Presenter 订阅的事件,要么调用 Presenter 上的方法,或者仅调用 Presenter 在构造 ViewModel 时向 ViewModel 提供的回调。本质上,它将操作委托给演示者。
  3. Presenter 在模型上调用 Add。
  4. 模型对 Add 调用做出反应,更新所有相关状态,包括普通旧集合。
  5. 演示者在模型上执行操作后,然后从模型中读取新状态并将该状态写入 ViewModel 中。绑定负责同步视图。

因此,在您的情况下,Presenter 可以订阅ViewModel 中CollectionChanged的事件ObservableCollection,当事件发生更改时,它会通过调用 Model 上的 Add 来对该事件做出反应。另一方面,当 Presenter 正在处理调用 Model 上的 Add 的其他用户操作时(它知道,因为它处理与 Model 的所有交互),那么它知道它必须将该更改传播到ObservableCollectionViewModel 中。

在我的代码中,我简化了情况......演示者在模型上执行每个用户操作后,我将模型中的所有相关状态直接复制到 ViewModel 中的适用位置。您所做的工作比需要的多一点,但在典型的 CRUD 类型的应用程序中,不存在明显的性能问题。如果我有一个非常大的对象集合,性能可能会成为问题,并且我会下降到更细粒度的同步(仅更新更改的实体),但代价是更复杂的逻辑。