应该在哪个类中包装EF实体?

时间:2017-10-18 09:36:18

标签: c# wpf entity-framework mvvm

我有一个使用MVVM实现编写的WPF应用程序。 MVVM模式没有额外的框架。

我首先将来自EF db的实体包装在他们自己的视图模型中,我有一个模型控制器,可以从“窗口”视图模型中将它们加载到视图模型中。

实体视图模型的示例:

public class PurchaseOrderViewModel : ViewModels.ViewModelBase
{
    private someType _prop;
    public someType Prop 
    {
        get
        {
            return _prop;
        }
        set 
        {
            _prop = value;
            OnPropertyChanged();
        }
    }

    // ... 
    // Other Properties
    // ... 

    public PurchaseOrderViewModel() {
        // default constructor for LINQ
    }
    public PurchaseOrderViewModel(purchaseorder entity)
    {
        // load values from entity in properties
    }
}

窗口视图模型示例:

public class MainViewModel: ViewModels.ViewModelBase
{
    private IModelController modelController = new ModelController();

    private List<PurchaseOrderViewModel> _poList;
    public List<PurchaseOrderViewModel> POList
    {
        get
        {
            return _poList;
        }
        set 
        {
            _poList = value;
            OnPropertyChanged();
        }
    }

    // ... 
    // Other Properties
    // ... 

    public MainViewModel()
    {
        POList = modelController.GetPurchaseOrders();
    }
}

ModelController示例:

public class ModelController : IModelController
{
    public List<PurchaseOrderViewModel> GetPurchaseOrders() 
    {
        using (var model = new DBContext())
        {
            return model.purchaseorders
                        .Select(new PurchaseOrderViewModel { /* assign properties */ })
                        .ToList();
        }
    }
}

一旦用户完成编辑,我应该在哪里保存这个包装的viewmodel(PurchaseOrderViewModel)?在我看来,有两个选择:

  1. 在每个viewmodel中创建一个指向modelController的保存函数,但这感觉就像是一种不合适的方法。
  2. 在modelcontroller中创建一个save函数,并将viewmodel作为参数传递
  3. 我很可能在MVVM模式中遗漏了一些内容,但请指出正确的方向。谢谢!

    编辑:我从提供的信息中排除了视图(MainView),但此视图直接绑定到MainViewModel公开的属性。

1 个答案:

答案 0 :(得分:2)

首先,我可能不会将其命名为ModelController,因为这会让人觉得你说的是MVC。相反,如果你称之为 xxxx Service(例如PurchaseOrdersService),它会更有意义,而且不再感觉&#34;不恰当&#34; 因为有一个 VM 委派实际工作是IoC的许多用户所做的事情。另外,它可以让您的 VM 保持清洁。

注意:通过&#34; service&#34; 我不一定意味着您的 VM 将会调用WCF服务直接(也不应该)。服务只是代表客户以抽象和封装方式实现某些目标的一种手段。例子包括:

  1. 将信息保存到数据库
  2. 获取当前日志机制
  3. 它们甚至可以是外墙,他们可以代表您创建WCF客户端代理并呼叫远程服务,而无需了解详细信息。
  4. 所以典型的流程是:

    命令&gt;&gt; 查看代码&gt;&gt; VM &gt;&gt;服务

    我将视图的代码包含在内的原因通常在于您:

    1. 抓住例外
    2. 用于 VM 和服务
    3. 的异步调用的async/await起点

      现在,当您将VM的上下文传递回服务时,没有关于您准确传递的内容的规则,但我认为没有理由将 VM 传递给服务,因为它包含服务不包含的信息#39; t关心。

      首先传递 VM 应该绑定的 M ,并继续通过绑定进行更新。