3

这是我的 2 个实体的设置:

public class Person {
  public Guid Id {get;set;}
  public string Name {get;set;}
}

public class Immortal : Person {
  public string DarkName {get;set;}
}

这是他们的映射的样子:

<class name="Person">
  <id name="Id">
    <generator class="guid.comb"/>
  </id>
  <property name="Name" />

  <joined-subclass name="Immortal">
    <key column='PersonId' />
    <property name="DarkName" />
  </joined-subclass>
</class>

这就是设置,2 个实体,一个是另一个的连接子类。我有一个搜索框架,它从表单中获取任意数量的条件,然后将适当的条件应用于查询,然后返回结果。

现在假设在这种情况下我有一个表单字段“姓名”——我想通过查看他们的姓名是否与 Person 的 Name 属性匹配来带回所有人,无论是普通的 Persons 还是特殊类别的生物 Immortals,但是对于不朽者,如果他们的 DarkName 与表格中给出的内容匹配,我也想将其视为匹配项。

所以这是我的困境,我该怎么做?我能用 NHibernate 的 ICriteria 做的最好的事情是在 Immortal 上进行子查询以检查那里的名称,然后查看根 Person id 是否在该子查询中。但是,在处理包含 10 多个数千人的表时,这种获取结果的方法非常低效,在我的现实世界中甚至会导致请求超时(30 秒以上)。

我也愿意在 HQL 中执行此操作,因为我想我希望在 Immortal 上进行外部连接以检查该字段,但我无法让 HQL 对任意属性上的 2 个不同实体进行连接——连接至我知道必须基于您的映射中的直接关联。例如,这是我希望看到的:

select person from Person person
  outer join Immortal immortal on immortal.PersonId = person.Id
  where
    person.Name = :name or
    immortal.DarkName = :name

你说什么stackoverflow?

4

1 回答 1

3

以下条件查询几乎完全生成了您想要的 SQL。

它利用了条件查询引擎中的一些松懈。

var list = session.CreateCriteria<Person>()
    .Add( Expression.Disjunction()
        .Add( Expression.Eq( "Name", name ) )
        .Add( Expression.Eq( "ImmortalName", name ) )
        )
    .List<Person>();

生成以下 SQL:

SELECT this_.Id             as Id0_0_,
       this_.Name           as Name0_0_,
       this_1_.ImmortalName as Immortal2_1_0_,
       case 
         when this_1_.Id is not null then 1
         when this_.Id is not null then 0
       end as clazz_0_
FROM   person this_
       left outer join immortal this_1_
         on this_.Id = this_1_.Id
WHERE  (this_.Name = 'foo' /* @p0 */
         or this_1_.ImmortalName = 'foo' /* @p1 */)

我使用了以下类映射:

<class name="Person" table="person">
    <id name="Id">
        <generator class="identity" />
    </id>
    <property name="Name" />
    <joined-subclass name="Immortal" table="immortal">
        <key column="Id" />
        <property name="ImmortalName" />
    </joined-subclass>
</class>
于 2010-02-21T14:34:27.523 回答