"重复关联路径"的解决方法NHibernate错误

时间:2014-10-29 15:37:47

标签: .net nhibernate

考虑一个Person表,其中每个名称(first,last,middle,...)存储在单独的表PersonName中,我想为每个Person选择两个不同的名称。

SQL看起来像:

SELECT firstName.VALUE, lastName.VALUE
FROM person p
inner join personName firstName on p.ID=firstName.PersonId AND firstName.Type='FIRSTNAME'
inner join personName lastName on p.ID=lastName.PersonId AND lastName.Type='LASTNAME'

我想用NHibernate创建这个查询。我的第一次尝试是使用QueryOver,但我遇到的是NHibernate issue

之后,我尝试使用SelectSubQuery,但它真的很慢+它使过滤/排序更加困难。

这是完全可能还是我需要恢复自己构建SQL?

更新
这必须是动态的,我不知道我必须选择哪个PersonName.Type。

PS:我在这里使用Person + Names作为简化示例。

2 个答案:

答案 0 :(得分:0)

你可以做table per class hierarchy。这意味着您将创建一个PersonName类,然后为First和Last名称类型(即PersonFirstName,PersonLastName类)创建子类。然后执行映射并为Type属性定义discrimator值。

<class name="PersonName" table="PersonName">
    <id name="Id" type="Int64">
        <generator class="native"/>
    </id>
    <discriminator column="Type" type="String"/>
    <property name="Value" />
    ...
    <subclass name="PersonFirstName" discriminator-value="FIRSTNAME">
        ...
    </subclass>
    <subclass name="PersonLastName " discriminator-value="LASTNAME">
        ...
    </subclass>
</class>

然后您的Person类将引用PersonFirstName和PersonLastName。

我希望这个表格设计有充分的理由,因为对于像名字这样的基本内容来说它似乎过于复杂。

<强>更新

要进一步限制为语言,您可以将其更改为集合,然后在联接中使用额外条件。

PersonFirstName fn = null;

var q = QueryOver<Person>()
.JoinAlias(
    x => x.FirstNames, 
    () => fn, 
    JoinType.InnerJoin, 
    Restrictions.Where<PersonFirstName>(x => x.Language = "en"));

答案 1 :(得分:0)

因为看起来这不会在NHibernate中修复(在他们的错误跟踪系统中标记为&#39; Trivial&#39;),我实际上是从Query-Over切换到HQL。

使用HQL执行完全相同的操作不会触发错误并按预期工作。