2010-11-17 115 views
0

以下是故事:一個網站(感興趣的物理位置)具有零個或多個聯繫人。這些聯繫人是與有權處理本網站事務的公司有關的人員。FluentNH將「深」關係模型映射到「展平」域對象

的模式是這樣的:

Person -< CompanyContact -<CompanySiteContact>- Site 
    || 
    | -< PersonPhone 
    | 
    -< PersonAddress 

我的切入點是網站。我需要聯繫人列表。除非你到達人員,否則很少有感興趣的現場數據。所以,我想將Person,CompanyContact和CompanySiteContact合併爲一個域類。

的選項,我想出了:

  • 創建一個域類和使用在FluentNH地圖加入到拼合圖層,因爲它檢索數據 。它從來沒有聽起來簡單,我遇到了多級聯接的問題(如果A聯接B聯接C,則不能在與B的聯接中指定與C的聯接)。然而,我認爲,如果可以指定連接,那只是一次性的事情,所以這將最終成爲最可維護的解決方案。

  • 在一組「DTO」中複製深層模型,該模型將1:1映射到表並可以傳遞給「平坦」域模型的構造函數。它的工作原理,但它感覺就像作弊(沒有任何問題不能用另一層抽象層解決,除了有太多的抽象層),我的直覺告訴我,這最終會導致更多的問題,而不是解決問題。

  • 使用架構複製域模型1:1並使用CompanySiteContact上的傳遞屬性訪問屬性在人員記錄深處的屬性。再一次,現在起作用,但它並不能真正解決問題,每一個變得有趣的新屬性都需要對映射,實際域類和頂級域類進行更改。不是很固體。

所以,Q是,我將如何構建映射?就像我說過的,我無法在連接中指定連接。我認爲我必須這樣做的方式是映射每個表的PK,並在頂層的下一個連接中使用它,但我不確定如何設置它(沒有使用FluentNH來設置任何接近這個複雜的東西)。

回答

0

感謝詹姆斯的回答; +1,但我認爲AutoMapper在這個時候不是必須的,而且我有點不自在地加入了能夠「自動」完成這項工作的東西。我想到了更多的選擇:

  • 在DB中設置視圖。這將工作,因爲由於業務規則,聯繫人信息是隻讀的;我正在開發的應用程序不能直接更新聯繫人,因爲不同的部門維護此rolodex。

  • 按照James的建議映射我的域名1:1,但是隨後使用Linq查詢將模型拼合成DTO。這個查詢可以封裝在Repository的幫助器中,允許開發人員直接使用Repository上的相同方法來查詢DTO和其他類。它比具有相同結果的視圖更復雜,但它不需要模式更改。

我可能會去第一個選項,如果有必要的話可以使用第二個選項。

+0

或者您可以使用AutoMapper輕鬆一點?你的替代方案聽起來像是你在遊戲後期爲自己設定了一個大泥球,尤其是你的第二選擇。說真的,一切都很神奇,直到你明白它是如何工作的。花一個小時玩AutoMapper,它會爲你節省很多痛苦。 – 2010-12-06 17:15:34

+0

好吧,我花了一點時間來看看AutoMapper,並且發現它比我在最初的樣子中看到的有更靈活(可定義)的配置選項。使用自定義映射,這是一個可行的,可維護的工具。我稱之爲「黑魔法」,因爲在「Mapper.CreateMap ()」的最簡單情況下,依靠默認的命名約定,在代碼中沒有任何東西可以指向映射得以實現。這將給一名開發人員帶來史詩般的偏頭痛,他們重新命名了一個房產,並且沒有明顯的理由打破了整個應用程序。 – KeithS 2010-12-06 18:23:41

+0

我認爲這個問題不是AutoMapper的「魔力」,而是開發者的教育。這同樣適用於Fluent NHibernate中的約定,StructureMap或Castle中的自動裝配,MVC中的路由;如果你只是參加並開始改變事情,那麼除非你已經接受了有關這些約定的教育,否則這些東西將會被打破。明確定義一切是避免教育開發人員的一種痛苦方式。 – 2010-12-08 09:26:37

2

我建議創建您的域模型以緊密匹配您的數據庫。從那裏我創建DTOs並使用AutoMapper來壓扁。簡單。

+0

+1,但我不認爲我們會使用AutoMapper。顯然,可配置性有點不理想,因此當代碼稍後維護時,它可能看起來像「黑魔法」。 – KeithS 2010-12-06 15:52:33