我玩过一些不同的Model-View-ViewModel实现,并且一直遇到一种情况,我不确定正确的方法。我知道MVVM的目标之一是将View与应用程序逻辑分离,以便在没有View的情况下测试逻辑。将逻辑放在ViewModel中,该ViewModel不依赖于View解决了这个问题。大。如果模型可以以可以模拟的方式与ViewModel分离,那就更好了。
所以我的问题是,ViewModel应该将模型与View分离吗?换句话说,通过ViewModel将EntityFramework实体暴露给View是否“可以”?例如,假设视图中有一个组合框,用户可以选择状态作为地址。在AddressViewModel中,State应该作为真实的实体类型属性公开,还是应该作为StateViewModel公开?如果它应该是StateviewModel类型的属性,我不明白如何在AddressViewModel.State setter中管理底层模型(因为在属性中设置的是StateViewModel而不是State实体)。
在我看来,这可能是两种方式,但似乎更加一致,从不直接将模型暴露给视图。想法?
答案 0 :(得分:4)
您应该努力将您的模型与您的视图完全分离,这应该是一个目标,您可能会遇到它,或者您可能不会,但仍然应该是您的目标。
具体来说,你的问题涉及一个常量列表(或多或少),这是一个简单的例子。如果我在这里错了,请纠正我,但是你可能有一个States
表,每个州有一个code
和一个name
,然后你有一个带有外键的表。前者。
在这种情况下,最好在应用程序初始化期间加载并创建StateViewModel
列表一次,然后在整个应用程序中处理外键值(状态code
) StateViewModel
个对象本身。您应使用的属性是SelectedValue
的{{1}}和SelectedValuePath
,例如:
ComboBox
这将使用<ComboBox ItemsSource="{x:Static StateViewModel.StaticList}"
SelectedValue="{Binding StateForeignKey}"
SelectedValuePath="code"
DisplayMemberPath="name" />
对象(使用现在处理的上下文创建)填充ComboBox
,但会将所选项目的StateViewModel
属性传递到绑定字段{{另外,code
将显示StateForeignKey
属性,以便人类可读。
答案 1 :(得分:2)
视图模型的目的是将视图与数据模型分离。如果视图中没有与数据模型耦合的功能,则不需要视图模型。
如果数据模型中有一个对象,其属性在创建后没有更改,并且视图不会修改,并且可以在UI中显示而无需格式化或转换,那么您不是通过直接暴露它将其任何功能耦合到视图。您不需要视图模型。
在你的例子中,你可能在没有创建StateViewModel
类的情况下逃脱,因为这样的类不会真正做任何事情。
答案 2 :(得分:1)
我通过viewmodel直接将实体绑定到我的视图,除非我必须为树视图添加特定的属性,如IsSelected等。如果我必须添加其他属性,那么我将viewmodel包装每个实体属性。
答案 3 :(得分:0)
您无法在ViewModel中公开Entity的原因是您不应该使用视图特定代码污染实体,例如IDataErrorInfo,INotifyPropertyChanged,IEditableObject等。
实体是应用程序核心,应该是POCO,可以在每种类型的应用程序中重用。例如,如果您开发可通过Mobile,Web和Desktop访问的应用程序,则无需为每种类型的应用程序创建实体。
解耦原因?对不起,但我不同意,因为我没有看到通过解耦Model和ViewModel有任何好处,因为单元测试在ViewModel中有或没有Entity时都能正常工作。<强>更新强>
抱歉,我忘了您使用的是EF4。默认情况下,EF4实体支持INotifyPropertyChanged,因此可以在ViewModel上公开您的实体。