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

我同意。我的消化不像你想的那样简单。但它最终在努力...... –