NHibernate:对单个表的多个映射

时间:2012-02-23 08:14:32

标签: nhibernate mapping

出于隐私原因,我有一个类,我想以两种不同的方式映射到单个表。让我们说这堂课看起来像这样:

class Person
{
   public int ID { get; set; }
   public string Name { get; set; }
   // ... many other properties omitted ...
}

相应的数据库表如下所示:

create table Person
(
   ID int not null,
   RealName nvarchar(512) not null,
   FakeName nvarchar(512) not null,
   -- many other columns omitted
)

我需要的两个映射是:

  • 名称属性到 RealName
  • 名称属性到 FakeName

在这两种情况下,所有其他属性应该映射相同。我强烈不希望重复这些其他属性的映射。

我尝试过几种不同的方法但没有运气。使用< union-subclass> 隔离不同的映射失败,并显示以下错误: DuplicateMappingException:Duplicate table mapping Person 。我可以创建两个不同的数据库视图,并分别映射到它们以避免重复的表映射错误,但这不是优选的。

使用“entity-name”属性来指定映射很有诱惑力,但文档记录很差,似乎有一些主要的缺点:a)它需要重复所有其他映射实体,和b)它与<多对一>不兼容来自引用Person类的其他类的关系。

有没有一种方法可以做到这一点,我错过了?

2 个答案:

答案 0 :(得分:0)

您可以使用NHibernate公式属性来匹配名称属性,如下所示

<property name="Name" formula="(SELECT id,(CASE WHEN yourcondition then RealName else FakeName end) as Name FROM Person)"/>

您可以参考的公式 - http://blog.khedan.com/2009/01/eager-loading-from-formula-in.html

答案 1 :(得分:0)

尽管我认为OP已经以某种方式解决了他的问题,但我还是想提出一个使用投影的解决方案。

基本上,在您的数据访问层(DAL)中,您可以选择使用投影列表访问数据的稍微复杂的方法,但取决于所需的FakePersonRealPerson类的实例你的逻辑。

它看起来像这样:

FakePerson alias = null;
var person = _session.QueryOver<Person>()
    .SelectList(list => list
        .Select(go => go.Id).WithAlias(() => alias.Id)
        .Select(go => go.FakeName).WithAlias(() => alias.Name) // <- the trick
        .Select(go => go.Other).WithAlias(() => alias.Other)
    .TransformUsing(Transformers.AliasToBean<FakePerson>());

您仍会使用PersonFakeName两个属性映射您的RealName类,但要将它们protected并从FakePersonRealPerson派生出来拥有公共Name财产的人。

我意识到你现在仍然需要两次列出所有属性,它刚刚从映射转移到DAL。好吧,也许这可以帮助那些人,无论如何。