2012-07-11 107 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

相關問題