0

我正在使用 MVP 创建应用程序:被动视图和 EF(模型优先)。据了解,我有一个演示者直接从通过 EF 创建的 DataContext 获取数据。它看起来像这样:

        private void UpdateOrderTableControl()
    {
        IList<Order> orders = dataContext.Orders.ToList();
        IList<OrderViewModel> viewOrders = new List<OrderViewModel>();
        foreach (var o in orders)
        {
            viewOrders.Add(new OrderViewModel()
            {
                OrderId = o.Id,
                CustomerId = o.CustomerId,
                LastName = o.Address.LastName,
                FirstName = o.Address.FirstName,
                Company = o.Address.Company,
                Weight = o.Weight,
                Sum = o.Sum,
                Date = o.Date
            });
        }

        view.GetOrderDataGridView().DataSource = viewOrders;
    }

所以presenter得到一个所有订单的列表,创建一个订单视图模型列表(结合来自不同表的数据,即上面的地址),然后将视图模型列表发送到视图。

反过来,从视图中检索数据以编辑或添加到数据库时,情况几乎相同:

        private void SaveOrder()
    {
        GetOrderDataFromView();

        if (isNewOrder)
        {
            dataContext.Orders.Add(selectedOrder);
        }
        else
        {
            dataContext.Entry(selectedOrder).State = EntityState.Modified;
        }

        dataContext.SaveChanges();
        isSaved = true;

        UpdateOrderTableControl();
    }

1) EF(通过 EF、DataContext 等创建的实体)可以被视为 DAL 吗?它应该在自己的项目中吗?

2)我猜演示者不应该像那样访问 DataContext ,而是访问两者之间的另一层,对吧?那是服务层,业务层还是两者兼而有之?

3)我所说的视图模型实际上是视图模型还是其他东西?我只是想让我的术语正确。

编辑:

4) 我阅读了一些关于向 EF 生成的实体添加业务逻辑的建议,但这对我来说听起来不太正确。我应该在 EF 之上的单独业务层中创建业务对象吗?这意味着我将拥有 Order(由 EF 生成)、OrderBO(业务对象)和 OrderViewModel(要显示的订单)。我将不得不做更多的映射,因为我会添加另一个图层,但它会使演示者更轻。

提前致谢!

4

2 回答 2

1

好问题!

好吧,所有这些的答案都取决于你打算做什么。您要做的第一件事是评估实现每种模式所需的努力是否值得付出痛苦。

1)您是否打算在不同的表单实现之间切换和/或仅对 UI 进行大量单元测试?那么是的,被动视图似乎是个好主意。

2)在表格里有一个小代码不是很痛苦吗?然后MVP监督控制器可以更快地实现。

3)您的程序的大部分逻辑可以在业务层内吗?在你拥有 BL 中的所有逻辑之后,有多少逻辑是特定于 GUI 的?如果不是那么多,那么在没有 GUI 模式的表单中编写代码就是要走的路。

关于问题:

1) 是的,EF 可以被认为是一个 DAL,并且在不同的项目中也没有什么坏处。由于您喜欢模式,因此这里有用的模式是存储库和工作单元模式,它抽象了 EF 并允许您对 BL 进行单元测试。(在不访问实际数据库的情况下进行测试,使用伪造的 DAL 实现)

2) 视情况而定。EF 对象可以被视为数据传输对象,因为它们是 POCO。DTO 在所有层中都可见。另一种策略是拥有特定于层的对象,主要是在分层应用程序的场景中(每一层在不同的机器上)。

如果不被迫这样做,我将使所有层都可见 EF 对象,但 DataContext 本身仅对 BL 可见,而不是 GUI 层。这意味着查询和事务是在 BL 中完成的,但 GUI 可以获得相同格式的结果。

3)如果您遵循上述建议,则不需要这种相当糟糕的对象复制。

4)你提到的这个策略是域模型(google for more),你把逻辑放在域对象中,也可以访问数据库。同样,如果您遵循 2) 中的建议,这不会打扰您。

不过,在对模式及其正确实现感到沮丧之前,请真正关注您的需求!目标是快速交付和易于维护。太多的抽象会伤害两者!

于 2013-09-01T16:22:21.820 回答
0

关于问题#2,最好对数据访问层进行区分和抽象。如果你继续将它保存在 Presenters 中,这意味着你的客户每次都会询问数据库,加载一些数据,然后进行一些计算。如果您正在处理客户端-服务器应用程序,最好不要混淆服务器逻辑和客户端逻辑。演示者肯定在客户端,DAL 在服务器端。您可以使用 Web 服务(例如 asmx、wcf)将客户端连接到服务器。我看到至少三个重要的理由这样做:

  1. 无需真正的后端和服务器逻辑即可在演示者上编写简单的单元测试
  2. 如果需要,扩展您的服务器端。
  3. 如果您在服务器端进行一些必要的计算,您将能够向客户端发送更少的数据

关于#3,对于被动视图模式,有一个 Presenter,它请求数据(有时称为模型),准备显示并发送到 View 进行渲染。在 Model-View-ViewModel 模式中,ViewModel 将向服务器发送请求并准备要显示的数据。MVVM 和 PassiveView 之间的区别 Presenters 和 ViewModels 如何使用 View。在 PassiveView Presenter 将知道 View 的接口以便能够发送数据进行渲染。在 MVVM 中,View 了解 ViewModel 并从 ViewModel 绑定数据。

最后一个,#1。我认为是的,它是一些基础设施层。如果在这里进行抽象,您将能够移动一些优化命令,设置加载选项(EF在这里非常灵活)并且您将能够快速完成。

于 2013-08-31T18:22:33.803 回答