5

我想构建一个基本的 wpf/mvvm 应用程序,它使用 WCF 从服务器获取数据并允许客户端显示/操作(使用 CRUD 操作)这些数据。

到目前为止,我为架构考虑过类似的事情:

  • 一个“全局”模型层,它实现验证、研究标准以及 INotifyPropertyChanged 和服务合同
  • 一些服务层,主要是实体框架 4,实现模型层的合同并允许我访问和操作数据。
  • 请注意,我也想要一个离线数据源,比如 XML 或其他东西,因此还有另一个服务(我计划使用一些 DI/IoC)
  • WCF 层
  • 数据存储客户端的额外层?
  • 视图模型

我对 Views/ViewModel 部分很清楚,但我很难弄清楚模型、WCF 和 viewmodel 之间的关系。

我的问题是:

  1. 我应该如何处理 EF 生成的模型?摆脱它并采用代码优先的方法,手动与数据库进行映射?
  2. 对于 WCF 数据传输,我的模型中是否应该有关系属性,即 Product 有 Customer 而不是 CustomerId ?
  3. 我是否应该在 WCF 和 ViewModel 之间增加一层来存储和操作数据,或者将 ViewModel 直接插入 WCF 是否是最佳实践?

欢迎任何其他关于这种架构的提示......

4

2 回答 2

4

对于 3 层 WPF 应用程序的体系结构有不同的解决方案,但这里有一种可能性:

1+2) 一种解决方案是创建代表客户端应用程序实际需要的“中间”对象。例如,如果您的应用程序需要显示有关产品的信息以及相关的客户名称,您可以构建以下对象:

public MyProduct
{
    // Properties of the product itself
    public int ProductID { get; set; }
    public string ProductName { get; set; }
    ...

    // Properties that come from the Customer entity
    public string CustomerName { get; set; }
}

然后,您可以公开一个无状态的 WCF 服务,该服务从一个 ID 返回您的产品:

[ServiceContract]
MyProduct GetProductByID(int productID);

在应用程序的服务器端(即服务的实现),您可以MyProduct通过 EF 查询数据库返回一个实例构建(每次调用一个上下文):

public MyProduct GetProductByID(int productID)
{
    using (DBContext ctx = new ....)
    {
        return from p in ctx.Products
            where p.ID == productID
            select new MyProduct
            {
                ProductID = p.ID,
                ProductName = p.Name,
                CustomerName = p.Customer.Name  // Inner join here
            };
    }
}

3) 在 WCF 服务和 ViewModel 之间添加额外的层可能被认为是过度工程。恕我直言,可以直接从 ViewModel 调用 WCF 服务。WCF 生成的客户端代理代码具有模型的实际作用(至少是模型的一部分)。


编辑:

为什么 MyProduct 应该引用 CustomerName 而不是 Customer。在我的例子中,Customer 会有很多我可以使用的属性。这个“映射”不会太贵吗?

您可以使用实际的实体。但在客户端,由于它是 3 层架构,您无法通过导航属性访问数据库。如果存在嵌套Customer属性(类型为Customer),则客户端将有权访问theProduct.Customer.Products,如果您不能以这种方式延迟加载实体(客户端没有数据库上下文),这毫无意义。

扁平的“中间”POCO 更简单 IMO。没有性能问题,映射很简单,与 DB 请求时间相比,此特定操作的 CPU 使用率是无限小的。

于 2012-07-11T12:54:42.393 回答
2

首先,一些一般信息:在 Lab49上有 Jason Dollinger 的关于 MVVM 的非常好的教程

编辑 该视频涵盖了构建 WPF 应用程序时的大部分需求。还介绍了依赖注入和与 WCF 的连接(但在谈到 WCF 时没有深入,但这里有一种非常强大的方法来提出好的解决方案)

他开发的源代码也可以在这里找到

在我看来,每个与 MVVM 相关的人都应该看到它!

=> 1.我应该如何处理EF生成的模型?摆脱它并采用代码优先的方法,手动与数据库进行映射?

AutoMapper 可以在这里提供帮助。AutoMapper 的 Codeplex 您的问题似乎非常适合这个!

=> 2. 对于 WCF 数据传输,我的模型中是否应该有关系属性,即 Product 有 Customer 而不是 CustomerId ?

不要乱用模型!productid 是订单的一部分,订单有一个 customer-id。坚持这一点。在您的服务层中,您可能最终会得到 id。因为您可能不会在这里更改产品或客户。如果你这样做(并且我的订单示例不适合),你可以传输动态数据,而不是静态数据。

=> 3. 我应该在 WCF 和 ViewModel 之间有一个额外的层,用于存储和操作数据,还是直接将 ViewModel 插入 WCF 是最佳实践?

在大多数情况下,我有一个服务层,它在构造函数中注入到我的视图模型中。这可以假设为另一层,因为它处理 WCF 客户端部分并处理服务器端的“更改”事件。(行更改,新行,行删除等)

编辑 如果您必须调度您的服务层事件,那么在 WCF 和 ViewModel 之间有一个小型、轻量级的层会容易得多。只要你必须,你很可能会自然而然地想出这样一个层。

于 2012-07-11T17:34:13.313 回答