0

對不起,一個漫長的問題。但值得提供所有細節,請耐心等待,直到最後。FluentNHibernate - 將一個類映射到多個表

我正在對一個遺留數據庫進行工作,但我沒有太多的控制權。我想能夠將一個類映射到多個數據庫表。這裏是我的表怎麼看

Lookup

+--------+--------------+------------+ 
| Column | DataType | Attributes | 
+--------+--------------+------------+ 
| Id  | INT   | PK   | 
| Code | NVARCHAR(50) |   | 
+--------+--------------+------------+ 

Culture

+--------------+--------------+------------+ 
| Column | DataType | Attributes | 
+--------------+--------------+------------+ 
| Id   | INT   | PK   | 
| Culture_Code | NVARCHAR(10) |   | 
+--------------+--------------+------------+ 

Lookup_t9n

+----------------+---------------+---------------------+ 
|  Column  | DataType |  Attributes  | 
+----------------+---------------+---------------------+ 
| Id    | INT   | PK     | 
| Culture_Id  | INT   | FK to Culture table | 
| Localised_Text | NVARCHAR(MAX) |      | 
+----------------+---------------+---------------------+ 

正如你所看到的,我有所有的查找存儲的查找表。查找的顯示文本已本地化並存儲在單獨的表中。此表具有文化表的外鍵以指示本地化文本存在的文化。

我的類看起來像這樣

public class Lookup { 

    public virtual int Id {get; set;} 

    public virtual string Code {get; set;} 

    public virtual string DisplayText {get; set;} 
} 

而且我FNH映射類看起來像這樣

public class LookupMappings : ClassMap<Lookup> { 

    public LookupMappings() 
    { 
     Table("Lookup"); 
     Id(x => x.Id).Column("Id"); 
     Map(x => x.Code).Column("Code"); 

     Join("Lookup_t9n", join => { 
      join.Map(x => x.DisplayText).Column("Localised_Text"); //Note this place, my problem is here 
     }) 
    } 
} 

在上面的映射,在Join部分,我想提供一些where子句像WHERE Lookup_t9n.Culture_Id = Culture.Culture_Id AND Culture.Culture_Code = System.Threading.Thread.CurrentUICulture.CultureCode

我知道這不是一個有效的SQL,但傳達了我希望的意圖。有沒有人有任何經驗做這樣的事情。

我可以添加一個映射圖層,我可以將類與數據庫表一對一地映射,然後編寫純c#將這些類映射回我的Lookup類。我寧願做爲臨時解決方案。我想知道是否可以使用某些智能NH來移除該映射層。

回答

1

我沒有簡單的答案,就像CallThis()。我想根據我們如何使用類似的東西給你提出建議。該解決方案基於標準映射,將其複雜性隱藏在C#實體中。這只是解決方案的草案,所以我會跳過中間的文化表,並期待在Lookup_t9n我們做存儲只是一個區域性名稱(ENCS ...)

讓我們這個類

public class Lookup { 
    public virtual int Id {get; set;} 
    public virtual string Code {get; set;} 
            // for simplicity skipping null checks  
    public virtual DisplayText { get { return Localizations.First().LocalizedText; } } 
    public virtual IList<Localization> Localizations {get; set;} 
} 

public class Localization { // mapped to Lookup_t9n 
    public virtual string CultureName {get; set;} 
    public virtual string LocalizedText {get; set;} 
} 

到這一點,我們可以在Localizations收集映射爲HasMany。它甚至可以映射爲組件(請參閱example of component mapping

現在,我們需要的是引入一個過濾器。 Example with Fluent。必要的文件:18.1. NHibernate filters

簡化測繪

過濾器:

public class CulturFilter : FilterDefinition 
{ 
    public CulturFilter() 
    { 
    WithName("CulturFilter") 
     .AddParameter("culture",NHibernate.NHibernateUtil.String); 
    } 

集合:

HasMany(x => x.Localization) 
    .KeyColumn("Id") 
    ... 
    .ApplyFilter<CulturFilter>("CultureName = :culture")) 
    .Cascade.AllDeleteOrphan(); 

最後,我們就來介紹一些AOP過濾器,IInterceptor ......這將在每次觸發(需要)並調整ISession

session 
    .EnableFilter("CulturFilter") 
    .SetParameter("culture" 
    ,System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName); 

現在我們有Localized字符串基於當前文化,同時使用本地化值的標準映射作爲集合。

+0

我已經解決了兩次你的解決方案,試圖讓我的頭部繞過它。我認爲我需要首先瀏覽您提供的所有鏈接並自行實施。 – Suhas

+0

我同意。我的消化不像你想的那樣簡單。但它最終在努力...... –