【问题标题】:EF4 + MVVM - Expose entities in ViewModel?EF4 + MVVM - 在 ViewModel 中公开实体?
【发布时间】:2011-05-08 00:43:03
【问题描述】:

我尝试过一些不同的 Model-View-ViewModel 实现,并且一直遇到我不确定正确方法的情况。我知道 MVVM 的目标之一是将视图与应用程序逻辑分离,以便可以在不存在视图的情况下测试逻辑。将逻辑放在不依赖于 View 的 ViewModel 中可以解决这个问题。伟大的。如果可以将 Model 与 ViewModel 以一种可以模拟的方式解耦,那就更好了。

所以我的问题是,ViewModel 是否应该将 Model 与 View 分离?换句话说,通过 ViewModel 将 EntityFramework 实体暴露给 View 是否“可以”?例如,假设视图中有一个组合框,用户可以在其中选择地址的州。在 AddressViewModel 中,State 应该作为真实的实体类型属性公开,还是应该作为 StateViewModel 公开?如果它应该是 StateviewModel 类型的属性,我不明白应该如何在 AddressViewModel.State 设置器中管理底层模型(因为在属性中设置的是 StateViewModel 而不是 State 实体)。

在我看来,这可能是任何一种方式,但似乎更一致的是从不将模型直接暴露给视图。想法?

【问题讨论】:

    标签: .net wpf silverlight entity-framework mvvm


    【解决方案1】:

    您应该努力将您的模型与您的视图完全分离,这应该是一个目标,您可能会实现它,也可能不会,但这仍然应该是您的目标。

    具体而言,您的问题涉及常量列表(或多或少),这是一个简单的案例。如果我在这里错了,请纠正我,但您可能有一个 States 表,每个州都有一个 code 和一个 name,然后您还有另一个表,其中包含前者的外键。

    在这种情况下,最好在应用程序初始化期间加载并创建一次StateViewModel 列表,然后在整个应用程序中处理外键值(状态为code)而不是@987654326 @ 对象本身。您应该使用的属性是ComboBoxSelectedValueSelectedValuePath,例如:

    <ComboBox ItemsSource="{x:Static StateViewModel.StaticList}"
              SelectedValue="{Binding StateForeignKey}"
              SelectedValuePath="code"
              DisplayMemberPath="name" />
    

    这将使用StateViewModel 对象(使用现在处理的上下文创建)填充ComboBox,但会将所选项目的code 属性传递给绑定字段StateForeignKey,此外,@ 987654335@ 将显示 name 属性,使其易于阅读。

    【讨论】:

      【解决方案2】:

      视图模型的目的是将视图与数据模型分离。如果视图中没有与数据模型耦合的功能,则不需要视图模型。

      如果您在数据模型中有一个对象,其属性在创建后不会更改,并且视图不会修改,并且可以在 UI 中呈现而无需格式化或转换,那么您不是通过直接公开将其任何功能耦合到视图。您不需要为此使用视图模型。

      在您的示例中,您可能无需创建 StateViewModel 类就可以逃脱,因为这样的类不会真正做任何事情。

      【讨论】:

      • 这在理论上是正确的,但在实践中,有时事情并不像人们(其中的开发人员)所想的那样恒定,例如,未来可能会扩展状态列表以包括其他国家等...
      • 这种变化不会对这个决定产生影响。向列表中添加新状态不会创建其属性在 UI 中可编辑的要求。
      【解决方案3】:

      我通过视图模型将实体直接绑定到我的视图,除非我必须为树视图添加特定属性,例如 IsSelected 等。如果我必须添加其他属性,那么我让 viewmodel 包装每个实体属性。

      【讨论】:

        【解决方案4】:

        你不能在 ViewModel 中暴露实体的原因是你不应该用视图特定的代码污染实体,例如 IDataErrorInfo、INotifyPropertyChanged、IEditableObject 等。

        实体是应用程序的核心,应该是POCO,可以在每种类型的应用程序中重用。例如,如果您开发一个可通过移动、Web 和桌面访问的应用程序,则无需为每种类型的应用程序创建实体。

        脱钩原因?抱歉,但我不同意,因为我认为解耦 Model 和 ViewModel 没有任何好处,因为无论有没有 ViewModel 中的实体,单元测试都可以正常工作。

        更新

        抱歉,我忘记了您使用的是 EF4。 EF4 实体默认支持 INotifyPropertyChanged,因此可以在 ViewModel 上公开您的实体。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-26
          • 2011-11-17
          • 1970-01-01
          • 1970-01-01
          • 2010-11-10
          • 1970-01-01
          相关资源
          最近更新 更多