2011-02-09 22 views
1

在我的項目(ASP.NET MVC + NHibernate的),我有我的所有實體,可以說Document S,由一組自定義元數據的描述。元數據包含在一個結構,它可以有多個標籤,類別等,這些術語,爲用戶獲得他們想要的文件最重要的,所以它有意見的影響,以及底層數據結構,數據庫查詢等複雜的分類ORM映射 - 尋找建議

從應用的角度來看,最讓我感興趣的是這些術語的字符串值。理想情況下,我想直接在琴絃一樣,集合操作:

class MetadataAsSeenInViews 
{ 
    public IList<string> Categories; 
    public IList<string> Tags; 
    // etc. 
} 

從模型的角度來看,我可以用相同的結構,做最簡單的,可能的ORM映射和使用它的查詢,如「獲取所有文件與元數據完全一樣「。

但是,這種結構可能變成無用的,如果應用程序需要執行復雜的數據庫查詢,如「獲取所有的文件,爲此,至少一個類是IN (cat1, cat2, ..., catN)或至少一個的標籤是IN (tag1, ..., tagN)」 。在那種情況下,出於性能原因,我們可能會使用數字鍵來輸入類別和標籤。

所以我們可以想象一個與MetadataAsSeenInViews相反的結構,它對數字鍵進行操作,併爲字符串和其他方式提供複雜的整數映射。但是,這種解決方案並沒有真正滿足我有以下幾個原因:

  • 它聞起來像單一職責違規,因爲我們正在處理的特定數據庫的問題時,只是想描述Document業務對象
  • 數據庫鍵通過所有層泄漏
  • 它增加了不必要的觀點
  • ,我相信它不好好利用一下可以很好的ORM做

理想的複雜性我想有:

  • 單,就這麼簡單,我整個應用程序只在數據庫層解決
  • 複雜查詢的問題的可能的元數據結構(理想情況下,如一個在頂部)(意爲DB + ORM +儘可能少的附加代碼用於數據層)

您是否有任何想法如何構造代碼並使ORM​​映射儘可能優雅,高效和高性能?

回答

0

我終於實現的解決方案並不能完全滿足我,但現在就完成了。

我把我的標籤/類別劃分爲「實體」,在NHibernate中映射爲獨立的實體和「引用」,映射爲依賴於它們描述的實體的組件。

所以在我的C#代碼中,我有兩個獨立的類 - TagEntityTagReference,它們都從域角度來看攜帶相同的信息。 TagEntity知道數據庫ID並由NHibernate會話管理,而TagReference僅攜帶標記名稱作爲字符串,因此在整個應用程序中使用它非常方便,如果需要,它仍然可以使用靜態查找字典很容易地轉換爲TagEntity

該實體/引用分隔允許我以更有效的方式查詢數據庫,僅連接兩個表,如select from articles join articles_tags ... where articles_tags.tag_id = X,而不加入tags表,在進行簡單的面向對象的NHibernate查詢時,該表也會加入。

0

我發現,這是有問題的,直接在視圖中使用域實體。爲了幫助解耦,我使用了兩種不同的技巧。

更重要的是我使用的是單獨的視圖模型類將數據傳遞給意見。當數據與領域模型實體很好地對應時,AutoMapper可以緩解在它們之間複製數據的痛苦,但是否則需要一些手動佈線。看起來像是開始時的許多工作,但是一旦項目開始增長就會有所幫助,尤其重要的是,如果您不僅僅是從頭開始設計數據庫。我還使用中間服務層來獲取ViewModel以保持控制器精簡併能夠重用邏輯。

第二個選項主要是出於性能原因,但我通常最終創建自定義存儲庫以獲取跨越實體的數據。也就是說,我創建了一個自定義類來保存我感興趣的數據,然後編寫自定義LINQ(或其他)來將結果投影到該類中。這通常可以顯着提高性能,而不僅僅是獲取實體,並在數據被檢索後應用投影。

如果我沒有詳細說明,請告訴我。

+0

謝謝。我熟悉MVVM模式,並在其他項目中使用它,但這裏並沒有完全說服我。該應用程序是隻讀的,數據庫可以專門爲視圖需求而設計(類似於簡單的CQRS而不需要查詢部分)。所以我覺得我的'元數據'已經是一種視圖模型。 – NOtherDev 2011-02-10 09:09:45