2012-07-11 108 views
4

我想构建一个基本的wpf/mvvm应用程序,该应用程序通过WCF从服务器获取数据,并允许客户机显示/操作(使用CRUD操作)此数据。WPF MVVM WCF客户机/服务器体系结构

到目前为止,我想过类似的东西为架构:

  • 一个“全球性”模型层,它实现验证,研究指标分析,并INotifyPropertyChanged的服务合同
  • 一些服务层,由主要是针对实体框架4,实现模型层的合同并允许我访问和操作数据。
  • 注意,我想有一个离线的数据源为好,说XML或别的东西,因而其他服务(我打算使用一些DI/IOC)
  • 的WCF层
  • 用于数据存储的客户额外的层边?
  • 视图模型

我的意见/视图模型部分清晰,但我有麻烦搞清楚模型,WCF和视图模型之间的关系。

我的问题是:

  1. 我应该如何处理由EF生成的模型?摆脱它,并去 代码第一种方法,手动做与 数据库的映射?
  2. 对于WCF数据传输,我应该在模型中使用关系型 属性,即产品有客户而不是 CustomerId?
  3. 我应该在WCF和 之间有一个额外的ViewModel层,用于存储和操作数据,还是最好的做法是直接将ViewModel插入到WCF中?

任何其他提示这种架构,欢迎...

+0

你可能想阅读我的回答http://stackoverflow.com/q/10437241/50079 – Jon 2012-07-11 12:46:33

+0

@Jon:你的答案确实很棒,谢谢。但是我还没有完全清楚模型部分,参见。我的答案ken2k – LaurentH 2012-07-11 13:59:23

回答

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; } 
} 

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

[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的应引用客户名称,而不是 Customer.In我的情况下,客户将有很多属性我工作 用。这个“映射”是不是太贵了?

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

平坦的“中间”POCO更简单IMO。没有性能问题,映射非常简单,与数据库请求时间相比,此特定操作的CPU使用率无限小。

+0

谢谢。你的答案对我有帮助,但我仍不清楚为什么MyProduct应该引用CustomerName而不是Customer。就我而言,客户将拥有许多我将使用的属性。这个“映射”是不是太贵了? – LaurentH 2012-07-11 13:58:55

+0

@LaurentH请参阅编辑答案 – ken2k 2012-07-11 17:12:32

+0

感谢您的帮助! – LaurentH 2012-07-12 10:59:34

2

首先,一些常规信息:有是由Jason多林格available at Lab49

编辑 在MVVM一个很好的教程构建一个WPF应用程序时,视频覆盖了大部分的需求。 依赖注入和WCF连接的(谈到WCF的时候,但 不深入,但一个真正强大的方式 拿出这里良好的解决方案)也包括在内

他所开发的源代码也available here

在我看来,所有与MVVM有关的人都应该看到它!

=> 1.如何处理由EF生成的模型?摆脱它,并采取代码第一的方法,手动做数据库的映射?

AutoMapper可以在这里帮助。 Codeplex of AutoMapper 你的问题似乎是一个完美的适合!

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

不要混淆模型! productid是订单的一部分,订单有客户ID。 坚持这一点。在你的服务层,你可能最终会用ids。 由于您可能不会在此更改产品或客户。如果你这样做(并且我的 订单示例不适合那么),您可以传输动态数据,而不是静态数据。

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

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

编辑 如果你有派遣服务层的事件,这是很容易有 是WCF和视图模型之间的小,leightweight层。只要你有 ,你可能会自然想出这样一个图层。

+0

谢谢。我已经听说过Jason Dollinger的教程,现在该看看它了! – LaurentH 2012-07-12 11:00:39

+0

强烈推荐!玩的开心! – 2012-07-12 11:04:50

相关问题