对于一个冗长的问题,我们深表歉意。但值得提供所有细节,所以请耐心等待我到最后。
我正在努力对付我无法控制的旧数据库。我希望能够将类映射到多个数据库表。这是我的表格的样子
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) | |
+----------------+---------------+---------------------+
如您所见,我有一个查找表,其中存储了所有查找。查找的显示文本已本地化并存储在单独的表中。此表具有culture表的外键,用于指示本地化文本所在的区域性。
我的班级看起来像这样
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 Lookup_t9n.Culture_Id = Culture.Culture_Id AND Culture.Culture_Code = System.Threading.Thread.CurrentUICulture.CultureCode
这样的where子句。
我知道这不是一个有效的SQL,但传达了我希望的意图。有没有人有这样做的经验。
我可以添加一个映射层,我可以在其中创建与数据库表一对一映射的类,然后编写plain c#以将这些类映射回我的Lookup
类。我宁愿这样做是一个临时解决方案。我想知道我是否可以使用一些智能NH来删除该映射层。
答案 0 :(得分:1)
我没有简单的答案,例如 CallThis()
。我想根据我们如何使用类似的东西给你建议。该解决方案基于标准映射,隐藏了其在C#实体中的复杂性。它只是解决方案的草稿,所以我将跳过中间的Culture表,并期望在Lookup_t9n
我们只存储一个文化名称( en , cs < / EM> ...)
我们有这个班级
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
字符串,同时使用本地化值的标准映射作为集合。