考虑一个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作为简化示例。
答案 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执行完全相同的操作不会触发错误并按预期工作。