2009-11-11 72 views
26

我正在研究WPF的MVVM設計模式。但我不確定在哪裏放置數據訪問代碼?MVVM在哪裏放置數據訪問層?

在我看過的一些例子中,直接在ViewModel中執行數據訪問。在ViewModel中放入像linq到sql這樣的東西似乎很奇怪?其他例子有一個獨立的數據訪問項目,這看起來更像嗎?

這是否有一個通用的方法?我覺得我在這裏錯過了一些東西!

謝謝

+2

有時會寫示例代碼來說明這一點。應該編寫生產代碼以保持和理解生產代碼。 – Min 2009-11-11 20:01:32

回答

11

我會添加另一層,本質上你想要的是一個數據工廠。你想創建一組類,這些類將會爲你的數據庫添加CRUD並將乾淨的POCO對象返回給ViewModel。

一個很好的例子,看看Nerd Dinner書。它涵蓋了MVC而不是MVVM,但模式非常相似,並且他們在該解決方案中訪問數據的方式將是一個很好的起點。

希望這會有所幫助。

+2

謝謝。我喜歡Nerd Dinner使用Repository模式的方式(正如Kristoffer所建議的那樣)。在文件結構方面,我認爲我將分離出Repository類和關聯的映射器到一個Data Access目錄。看起來好像它是MVVM中未提及的大面積。再次感謝。 – 2009-11-11 21:14:26

+0

NerdDinner示例的確是存儲庫模式的一個很好的例子。但是,它們在視圖中暴露了領域模型(即他們不使用MVVM),這被認爲是不好的做法。 – Kristoffer 2009-11-11 21:29:55

+0

@ Lukasz,在書呆子晚餐時,他們直接調用linq到sql方法。那好嗎?模型會是生成frol linqtosql的類嗎? – 2012-05-05 05:48:44

5

MVVM代表型號查看視圖模型。您缺少的部分是模型,這是您的數據訪問代碼所在的地方。

視圖模型都是在模型並將其呈現給View顯示,所以通常你會是這樣的:

class PersonModel : IPerson 
{ 
    // data access stuff goes in here 
    public string Name { get; set; } 
} 

class PersonViewModel 
{ 
    IPerson _person; 

    public PersonViewModel(IPerson person) 
    { 
     _person = person; 
    } 

    public Name 
    { 
     get { return _person.Name; } 
     set { _person.Name = value; } 
    } 
} 

PersonView會然後綁定到PersonViewModel的特性,而不是直接向模型本身。在許多情況下,你可能已經擁有了一個對MVVM一無所知的數據訪問層(也不應該這樣做),但是你仍然可以構建ViewModel來將其呈現給視圖。

+1

選擇這一個。 – 2009-11-11 20:34:10

+0

查看http://jonas.follesoe.no/YouCardRevisitedImplementingTheViewModelPattern.aspx – 2009-11-11 20:41:23

+0

值得注意的是,這將很難在多數據庫場景中實現,因爲您需要將db上下文傳遞給模型。這是我們使用存儲庫模式的主要原因......將CRUD放在單獨的類庫中。你的里程會有所不同。 – 2012-06-05 20:38:57

10

數據訪問應該而不是在視圖模型中,因爲這應該是視圖特定(可能簡化)的領域模型表示。

使用某種映射器將您的視圖模型(MVVM中的VM)映射到您的模型(第一個M)。可以使用工廠模式創建模型中的新對象。一旦創建,您可以使用存儲庫模式將它們存儲在數據庫中。這些存儲庫將代表您的數據訪問層。在你的倉庫中,你可以使用像NHibernate或Entity Framework這樣的O/R映射器。

編輯:
我看到GraemeF建議把數據訪問代碼的模型。這是一個很好的方法,因爲如果您要從例如移動到其他位置,這會迫使您更新域模型。 SQL Server到Oracle或XML文件。 域對象不應該擔心它們如何被持久化。存儲庫模式將域與其持久性隔離。

+1

好點;當然你可以進一步深入。我的觀點是,數據訪問代碼隱藏在該接口後面,並且不在ViewModel中。 – GraemeF 2009-11-11 20:56:23

1

您的ViewModel應該是一個僅服務於視圖的薄層。我的經驗法則:如果它與UI的呈現有關,那麼它屬於ViewModel,否則它應該在Model中。

40

下面是我一直在整理我的MVVM瓦特/ LINQ項目:

模式 - 我認爲模型作爲系統的狀態。它爲數據提供了一個接口,並跟蹤系統狀態。 Model不知道ViewModel或View--它只是爲其數據和各種事件提供公共接口,讓消費者(通常是ViewModels)知道狀態何時發生變化。

ViewModel - ViewModel負責組織或構造View所需的所有數據,跟蹤視圖的狀態(例如當前選定的數據網格行)以及響應動作在視圖上(如按鈕按下)。它知道什麼需要,但它實際上並不知道該視圖。

查看 - 視圖是界面的實際外觀。它包含所有內置和自定義控件,它們如何排列以及它們的樣式。它知道ViewModel,但僅用於綁定其屬性。

網關 - 這是直接解決您的問題的部分。網關(這基本上是我說「DataAccessLayer」的方式)是它自己的獨立層。它將所有代碼(包括LINQ查詢)包含到CRUD中,或從數據源(數據庫,XML文件等)中選擇,插入,更新和刪除數據。它還提供了模型的公共接口,使模型可以專注於維護系統狀態,而不必關心更新數據源所需的細節(即查詢)。

DataAccess類 - 在C#中,這些都是非常簡單的類,它們爲您的基本數據對象建模。當您使用LINQ查詢來選擇某些內容時,通常會創建一個IEnumerable<T>List<T>,其中T是您的一個數據對象。一個數據對象的例子是:

public class Person 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
} 

像這樣的設計的一大優勢是,它真的分離你的顧慮。每件事都有專門的工作,而且通常很容易知道哪裏會發生什麼樣的事情。

缺點是對於小項目來說這可能是過分的。你最終爲公共接口創建了很多基礎設施,基本上可以通過多個層來傳遞一個願望。所以,你最終可能會出現這樣的情況:[用戶點擊Submit,ViewModel告訴Model爲AddNewPerson,Model告訴Gateway爲InsertPerson]而不是像這樣的場景[用戶點擊Submit,ViewModel直接向數據庫添加新記錄]。

希望有所幫助。

+7

能否請你提供一個你對mvvm解釋的簡短例子,因爲如果搜索到好的DAL解決方案,我總是遇到死路一條 – WiiMaxx 2013-02-05 16:12:30