WPF MVVM WCF客户端/服务器体系结构

Lau*_*ntH 5 architecture wpf wcf mvvm

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

到目前为止,我为这个架构考虑了类似的东西:

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

我对Views/ViewModel部分很清楚,但是我很难搞清楚模型,WCF和viewmodel之间的关系.

我的问题是:

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

欢迎任何其他有关此类架构的提示......

ken*_*n2k 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; }
}
Run Code Online (Sandbox Code Playgroud)

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

[ServiceContract]
MyProduct GetProductByID(int productID);
Run Code Online (Sandbox Code Playgroud)

在应用程序的服务器端(即服务的实现),您可以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
            };
    }
}
Run Code Online (Sandbox Code Playgroud)

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


编辑:

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

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

在我看来,扁平化的“中间”POCO 要简单得多。不存在性能问题,映射很简单,并且与数据库请求时间相比,此特定操作的 CPU 使用率非常小。