2010-05-19 87 views
4

設計可以具有多語言字段的域對象的最佳方式是什麼?一個示例可以是一個Product類,其中Description是多語言的。使用NHibernate實現多語言域對象的最佳方法是什麼?

我發現有幾個鏈接,但無法確定哪一個是最好的方法。

  1. http://fabiomaulo.blogspot.com/2009/06/localized-property-with-nhibernate.html
    (此店在一個領域的所有本地化語言的數據。可能是一個問題,如果我們從SQL查詢)

  2. http://ayende.com/Blog/archive/2006/12/26/LocalizingNHibernateContextualParameters.aspx
    (這其中有在開始時警告稱,是一個黑客,不再支持)

  3. http://www.webdevbros.net/2009/06/24/create-a-multi-languaged-domain-model-with-nhibernate-and-c/
    (這並沒有描述多語言數據將如何在數據庫中構建。)

任何人都有使用NHibernate和多語言數據的經驗。有沒有更好的辦法?

回答

2

第三個選項看起來不錯。 Hibernate映射給定,而不是數據庫模式 - 如果這是你錯過了什麼,然後我會在這裏勾勒出來:

dictionary 
---------- 
ID: int - identity 
name: nvarchar(255) 

phrase 
------ 
dictionary_id:int (fkey dictionary.ID) 
culture_id:int  (LCID) 
phrase:nvarchar(255) - this is the default size - seems too small 

this blog entry,255是字符串值的默認字符串長度。爲了克服該短語的文本短字符串的長度,你可以在<element>標籤更改爲

<element column="phrase" type="String" length="4001"></element> 

要在您的域模型使用這個,你PhraseDictionary屬性添加到您想要翻譯的文本你的實體。例如。標題屬性或解鎖屬性。

我認爲這篇文章描述了一個很好的方法,並且我會去 。

編輯:在回覆評論時,如果您知道絕對最大尺寸小於4001,則長度應小於4001,因爲這通常會更快。另外,NHibernate會懶洋洋地抓取集合,但它可能會一次抓取所有的項目。您可以通過配置文件來確定這是否有任何性能影響。 (如果你只有少數語言,那麼我懷疑你會看到區別。)如果你有很多語言(比如說50+),那麼創建自定義屬性來獲取本地化文本可能是值得的。這些將發出查詢來獲取所需的文本。更重要的是,您可以在一個查詢中獲取給定實體的所有文本,而不是將每個本地化文本屬性作爲單獨的查詢。

請注意,如果性能分析讓您有理由關注性能,則只需要額外的努力。有可能這篇文章中的實現將起到更好的作用。

+0

請注意,長度超過4000 Sql Server(> = 2005)將數據放在LOB結構而不是表結構... 此外,請記住,第三個解決方案將獲取所有語言應用任何性能影響的'短語' – Jaguar 2010-06-02 07:29:11

+0

@Jaguar - 你對nvarchar(4001)是正確的。如果您知道短語短於4000,請設置適當的尺寸。至於提取所有短語,我不太確定。看起來HHibernate在默認情況下會進行延遲加載,所以我希望它只會按需加載set。但是,它可能會加載整個集合。你可以通過編寫一個標準來獲取當前文化的短語來避免這種情況。你可以把它放在實體的getter方法後面。 – mdma 2010-06-02 14:36:34

1

我只有Hibernate的經驗,但由於NHibernate的是如此的相似:

一個選項是定義與成員爲每種語言組件類型MultilingualString(假定該集合的編碼時間是已知的語言)。這種類型也是一個方便的位置,通過語言ID爲字符串放置一個getter。

class MultiLingualString { 
    String english; 
    String chinese; 
    String klingon; 

    String forLanguage(Language lang) { 
     switch (lang) { 
      // you can guess what goes here 
     } 
    } 
} 

這將導致串所有語言被存儲在單獨的列在數據庫中,而在對象世界中表示保留細粒度。

優點是不需要連接來獲取字符串。另一方面,不使用這種方法獲取字符串的唯一方法是使用投影,如果字符串很大,很多並且很少需要,這是一個嚴重的限制。

如果你這樣做了很多,編寫一個UserType可能是值得的。

+0

這種方法的問題在於,我們在可以是多語言的數據庫中有多個列。如果有n列和m種語言,那麼它可以是(m * n)表中額外的列,如果我沒有錯的話。 – Amitabh 2010-06-04 14:26:10

+0

*(m * n)個字符串列的*總數*。是的,這裏有一個權衡。但是因爲我不知道m和n,所以似乎值得一提的是這種可能性。 – meriton 2010-06-04 18:30:52

1

從SQL Server嚴格的面向數據庫的角度來看,您應該有一個包含所有基本數據(記錄鍵,日期,數字等)的表以及一個包含所有可轉換字符串數據的表。讓我們調用兩個表Base和Base_Description。

Base確保每個記錄都有一個密鑰,密鑰可能是字符串或自動生成的ID,具體取決於您的特定用例。

Base_Description表與Base表相關,但也包含一個值,用於選擇數據所在的語言。在我的項目中,我們使用sys.languages的langid列,因爲我們可以使用來設置連接的語言然後用@@ LANGID抓住它來做大部分操作。

在我們的測試中,我們發現這比每種語言有多個字段要快得多,它還允許您更輕鬆地添加其他語言。我們也使用SQL Server全文索引,並且完全支持這種方法。您應該使用中性語言編制索引,然後您可以在運行時選擇要搜索的語言(也可以針對Base_Description中的LangID列進行篩選)。

1

您的要求是否包含在同一對象中實際具有多語言屬性的域對象?而且,如果是這樣的話,它是否存在無限的翻譯存儲在對象中(在一個集合中,比如說 - 在這種情況下,我會說它需要像任何主/細節或父/子集合一樣)或固定翻譯,其中情況下語言(因此映射到存儲過程的結果或其他)必須靜態確定?

在我工作的許多國際化應用程序中,數據只有一種語言 - 客戶名稱,產品名稱(即使在一個國家/地區中使用同一產品的產品名稱也沒有意義,它們都有不同的分銷商和不同的SKU,當然還有本地化的定價)。該界面也只有一種語言(一次)。所以所有的域對象一次只需要一種語言。因此,翻譯的語言將在對象被實例化時確定。

我們有允許用戶更新翻譯文本的翻譯用戶界面,但這些用戶界面一次只需要兩種語言(本地和默認)。我可以看到這與你所說的最接近。我猜你會爲每個可翻譯的房產收集所有可能的翻譯集合。這可能與您鏈接的第三篇文章中的第二個解決方案最接近。當然,在這一點上,你還需要看看你是否想要急切/懶加載等

+0

我的要求確實包括具有多語言屬性的域對象。 – Amitabh 2010-06-07 14:46:31

+0

@Amitabh然後,我會去與傳統的父/細節結構。與您用於將一個電話號碼存儲到客戶端等相同。 – 2010-06-07 15:10:02

相關問題