FluentNHibernate - 将一个类映射到多个表 [英] FluentNHibernate - Mapping a class to multiple tables
问题描述
抱歉问了一个冗长的问题.但值得提供所有细节,所以请耐心等待.
Sorry for a lengthy question. But it is worth giving all the details so please bear with me through to the end.
我正在处理一个我没有太多控制权的旧数据库.我希望能够将一个类映射到多个数据库表.这是我的表格的外观
I'm working against a legacy database over which I do not have much control. I want to be able to map a class to multiple database tables. Here is how my tables look
查找
+--------+--------------+------------+
| Column | DataType | Attributes |
+--------+--------------+------------+
| Id | INT | PK |
| Code | NVARCHAR(50) | |
+--------+--------------+------------+
文化
+--------------+--------------+------------+
| 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) | |
+----------------+---------------+---------------------+
如您所见,我有一个查找表,其中存储了所有查找.查找的显示文本已本地化并存储在单独的表中.该表具有文化表的外键,以指示本地化文本所在的文化.
As you can see, I have a lookup table where all lookups are stored. The display text for a lookup is localized and stored in a separate table. This table has a foreign key to culture table to indicate the culture for which the localized text exists.
我的班级是这样的
public class Lookup {
public virtual int Id {get; set;}
public virtual string Code {get; set;}
public virtual string DisplayText {get; set;}
}
我的 FNH 映射类看起来像这样
And my FNH mapping class looks like this
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.文化代码
.
In the above mapping, in Join
part I want to provide some where clause like WHERE Lookup_t9n.Culture_Id = Culture.Culture_Id AND Culture.Culture_Code = System.Threading.Thread.CurrentUICulture.CultureCode
.
我知道这不是一个有效的 SQL,但传达了我希望的意图.有没有人有做这样的事情的经验.
I know this is not a valid SQL but conveys the intent I hope. Has anyone have any experience of doing such a thing.
我可以添加一个映射层,我可以在其中拥有与数据库表一对一映射的类,然后编写普通的 c# 将这些类映射回我的 Lookup
类.我宁愿这样做作为临时解决方案.我想知道我是否可以通过一些巧妙的 NH 使用来删除该映射层.
I can add a mapping layer where I can have classes that map one-to-one with database tables and then write plain c# to map those classes back to my Lookup
class. I have rather done that as an interim solution. I was wondering if I can remove that mapping layer with some smart NH use.
推荐答案
我没有简单的答案,比如CallThis()
.我想根据我们如何使用类似的东西给你建议.该解决方案基于标准映射,将其复杂性隐藏在 C# 实体中.这只是解决方案的草稿,所以我将跳过中间的 Culture 表,并期望在 Lookup_t9n
中我们只存储一个区域性名称(en,cs...)
I do not have simple answer, like CallThis()
. I would like to give you suggestion, based on how we are using similar stuff. The solution is base on the standard mapping, hidding its complexity in C# Entities. It is just a draft of the solution so I'll skip the middle Culture table, and will expect that in Lookup_t9n
we do store just a culture name (en, cs...)
我们来上课
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
的 collection 映射为 HasMany
.它甚至可以映射为组件(参见组件映射示例)
Having this, we can map the collection of Localizations
as HasMany
. It could even be mapped as a component (see example of component mapping)
现在,我们需要引入一个过滤器.Fluent 示例.基本文档:18.1.NHibernate 过滤器.
Now, what we do need is to introduce a filter. Example with Fluent. The essential documentation: 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
Finally, we have to introduce some AOP filter, IInterceptor... which will be triggered each time (needed) and adjust the ISession
session
.EnableFilter("CulturFilter")
.SetParameter("culture"
,System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName);
现在我们有了基于当前文化的Localized
字符串,同时使用本地化值的标准映射作为集合.
And now we have Localized
string based on current culture, while using standard mapping of localized values as a collection.
这篇关于FluentNHibernate - 将一个类映射到多个表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!