在MVVM中,使用实体框架填充视图模型的内容是什么?

时间:2016-03-25 18:33:28

标签: c# wpf entity-framework mvvm

我正在编写WPF桌面应用程序。我试图理解MVVM数据流。我使用Entity Framework作为数据访问,并且我使用了代码优先的方法,因此我拥有代表每个SQL表的POCO实体类。

通过这种配置,我的理解是我的模型(MVVM中的M)是我的POCO实体类。我的观点(MVVM中的V)是我的WPF窗口。

什么填充了我的视图模型?我只是在视图中进行EF查询,填充视图模型吗?我的视图模型是否执行自己的查询(可能是在类内部构造函数中)?

2 个答案:

答案 0 :(得分:3)

通常,视图是WPF窗口,它背后是相应的代码。视图模型是一个简单的类,用于处理特定视图的数据层要求并进行处理。通常在控件的XAML视图中使用命令,并且每个命令都绑定到视图模型中的命令实例。可以通过依赖注入创建视图模型,也可以将其传递到后面的视图代码中的构造函数中,并将其作为成员/属性存储在后面的代码中。确保将视图数据上下文设置为视图模型的实例,以便允许绑定到视图模型中的属性和命令。

this.DataContext = new TheViewModelType();

实体框架普通旧CLR对象是数据模型,视图通常不应该知道这些。视图模型可以具有视图可以绑定的模型类型的属性,例如项目控件等。所以在视图中:

<ItemsControl x:Name="CarItems" ItemsSource="{Binding Vm.CarsCollection}"></ItemsControl>

因此,由于视图的DataContext是视图模型类型的实例,因此视图控件可以直接绑定到视图模型中的属性。示例是具有Cars集合的视图模型,并且视图模型可以在需要时调用服务以填充Cars集合。显然汽车是模型。

    public MyViewModel( )
    {
        Cars = TheCarsDataLayerService.GetCars( );
    }

    private IObservable<Car> _cars;

    public IObservable<Car> Cars
    {
        get { return _cars; }
        set
        {
            if( _cars == value )
                return;
            _cars = value;
            RasisePropertyChanged("Cars");
        }
    }

对于示例中的Cars服务,这可以是数据层存储库,也可以是Entity Framework DbContext的实例。所以视图模型可以有一个DbContext派生类型的字段或者这样的服务,这可以传递给视图模型类的构造函数或者用依赖注入注入,或者服务是静态工厂或单例那个视图模型只需调用以使用视图将向用户显示的数据填充其成员。

MVVM是一种非常基本的设计模式,可以通过多种不同方式实现。一些开发人员会将模式提升到新的高度,并严格遵守模式组件通信的许多规则。最终,使用模式比不使用任何模式要好得多,无论它是如何实现的,因为它将允许代码更好地扩展,而其他开发人员可能更容易理解代码并期望某些事情。此外,MVVM模式允许WPF开发人员进行单元测试。如果做得足够好,可以测试视图模型,因为后面的视图代码中没有代码,并且视图除了显示它甚至不知道的数据之外什么都不做,测试视图模型很好。

答案 1 :(得分:1)

严格使用您的域模型作为视图模型最终会立即导致您出现问题。通常,域模型由原始数据组成,它可能包含也可能不包含业务操作,有些可能会将其放在BusinessLayer管理器类中。但是你的VM ViewModel严格来说是视图,应该只存在于视图项目中。使用与视图相关的下拉菜单等混乱您的域名...不适合放置那些&#34; View&#34;数据来源。

因此,为了将其置于代码术语中,您的视图模型可以包含引用域模型实例的属性,或者您可以添加视图将公开的每个属性。但是通过分离ViewModel和Model(域模型),您允许视图能够公开/隐藏它所需的内容以及转换某些属性,例如,EntityFramework模型可能包含字符串属性,但您的视图可能需要严格它在一个屏幕上的数字表示,而另一个可能允许编辑为字符串属性,点是您的EF模型(域模型)不需要担心这些视图问题。

您在哪里创建VM?

控制器的工作是解释请求并确定所需的视图和视图模型。因此,在控制器中,使用EF域模型类(以编辑请求为例)创建VM作为VM的源。