"duplicate association path" NHibernate 错误的解决方法



考虑一个Person表,其中每个名称(第一个、最后一个、中间…)都存储在一个单独的表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问题。

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

这有可能吗?还是我需要恢复到自己构建SQL?

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

附言:我在这里使用Person+Names作为一个简化的例子。

您可以按类层次结构创建一个表。这意味着您将创建一个PersonName类,然后为First和Last name类型(即PersonFirstName、PersonLastName类)创建子类。然后进行映射并为Type属性定义描述符值。

<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"));

因为看起来这在NHibernate中不会被修复(在他们的错误跟踪系统中标记为"琐碎"),所以我实际上从Query Over切换到了HQL。

对HQL执行完全相同的操作不会触发错误,并且可以按预期工作。

最新更新