NHibernate:同一查询中实体和可能的子类的查询条件
这是我的 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 个实体,一个是另一个的连接子类。我有一个搜索框架,它从表单中获取任意数量的条件,然后将适当的条件应用于查询,然后返回结果。
现在假设我在这种情况下有一个表单字段“Name”——我想通过查看他们的名字是否与 Person 的 Name 属性匹配来带回所有人,无论他们是普通人还是特殊类别的不朽生物,但是对于不朽者,如果他们的 DarkName 与表格中给出的内容匹配,我也想将其视为匹配。
这就是我的困境,我该怎么办?我能用 NHibernate 的 ICriteria 做的最好的事情就是在 Immortal 上创建一个子查询来检查那里的名称,然后查看根 Person id 是否在该子查询中。然而,当处理数十或数千人的表时,这种获取结果的方法效率非常低,甚至在我的现实情况下可能会导致请求超时(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
What say you stackoverflow?
This is the setup for my 2 entities:
public class Person {
public Guid Id {get;set;}
public string Name {get;set;}
}
public class Immortal : Person {
public string DarkName {get;set;}
}
Here is what their mappings look like:
<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>
So that's the setup, 2 entities, one is a joined subclass of the other. I have a search framework that takes any number of criteria from a form and then applies the appropriate criteria to a query, then returns the results.
Now say I have a single form field in this case, "Name" -- I want to bring back all people, be they normal Persons or that special class of beings Immortals, by seeing if their name matches the Name property of Person, but in the case of an Immortal, I'd also like to count it as a match if their DarkName matches what was given in the form.
So this is my dilemma, how do I do this? The best I have been able to do with NHibernate's ICriteria stuff is to make a subquery on Immortal to check the name there, and then see if the root Person id is in that subquery. When working with a table of 10s of thousands of Persons, however, this method of getting results is extraordinarily inefficient and can even time out the request (30s+) in my real world situation.
I would be open to doing this in HQL too, because I figure I want an outer join on Immortal to check for this field, but I cannot get HQL to do a join on 2 disparate entities on an arbitrary property -- joins as far as I know must be based on direct associations in your mappings. For instance, this is what I would like to see:
select person from Person person
outer join Immortal immortal on immortal.PersonId = person.Id
where
person.Name = :name or
immortal.DarkName = :name
What say you stackoverflow?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
以下条件查询几乎可以生成您想要的 SQL。
它利用了条件查询引擎中的一些宽松性。
生成以下 SQL:
我使用了以下类映射:
The following criteria query produces almost exactly the SQL that you want.
It takes advantage of some laxness in the criteria query engine.
produces the following SQL:
I used the following class mapping: