我有一个看起来如下的对象......
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping namespace="test" assembly="test" xmlns="urn:nhibernate-mapping-2.2">
<class name="Person" table="`Person`">
<id name="ItemId" access="property" column="`ItemId`">
<generator class="native" />
</id>
<property name="Name" column="`A`" />
<property name="Age" column="`B`" />
<set name="Email" inverse="true">
<key column="`Name`" />
<one-to-many class="EmailClass" />
</set>
</class>
</hibernate-mapping>
我想通过电子邮件地址
来执行nHibernate查询来过滤这些记录我已经尝试过这些方法......
var childCriteria = QueryOver.Of<EmailClass>().Where(c => c.EmailAddress.ToString().IsLike("%" + strSearch + "%")).Select(c => c.EmailID);
var query = session.QueryOver<Person>().WithSubquery.WhereExists(childCriteria).Future();
我显然做错了什么。问题是,是否可以搜索数据对象的子集?或者直接搜索子表然后找到它的父项是否更好?
答案 0 :(得分:1)
你可能想要:
session.QueryOver<Person>()
.JoinQueryOver(p => p.EmailClass)
.Where(e => e.EmailAddress.IsLike(strSearch, MatchMode.Anywhere))
.Future<Person>();
这假设EmailClass.EmailAddress
是string
。
这将生成如下所示的SQL:
select
Person.* /* all person fields */
from
Person
inner join EmailClass on EmailClass.Name = Person.Name
where
EmailClass.EmailAddress like '%strSearch%' /* your search term */
答案 1 :(得分:1)
我差不多到了,我说。
予。首先映射的一些注释...
首先,我假设EmailClass
与Person
以及有关系(因为在DB级别这是双向关系)。
public class EmailClass
{
...
public virtual Person Person { get; set; } // inverse mapping
}
这是合乎逻辑的,因为无论如何这个DB关系是存在的。它已被表达为名为<set>
的人Email
。并且也应该是必须的,因为我们使用 inverse="true"
,这需要双向映射......
这也让我对映射提出质疑。您确定,这种映射是正确的:
<class name="Person" ...
// KEY column of this entity is ItemId (seems to be int)
<id name="ItemId" column="`ItemId`" ...
...
<set name="Email" inverse="true">
// this mapping says: NHibernate, try to find the value
// of the ItemId in the Person table
// in the column Name of the table EmailClass ... ?
<key column="`Name`" />
...
// would expect
<key column="ItemId" /> // column inside of EmailClass table
我想说,通常,我们可以看到,用作根实体(人)的键的<id>
列名称与{{1}相同用于集合映射的列。
因此,我希望the <key>
表格应包含列,例如EmailClass
或"ItemId"
,这样可以保留对{{1}的引用表格。
II。子查询过滤
现在让我们继续查询,期待以上情况属实。
"Person_ID"
所以,正如我们所看到的,几乎就是...... LIKE的一些 QueryOver-ish 样式,以及必要的WHERE子句Person = EmailAddress.Person
III。映射...建议
请允许我提供一些我期望/建议的映射草案:
Person
映射:
// An Alias, to be used later
Person person = null;
var childCriteria = QueryOver
.Of<EmailClass>()
// more QueryOver native style of a LIKE expression
.WhereRestrictionOn(c => c.EmailAddress).IsLike(strSearch, MatchMode.Anywhere)
// trick here
// if we want to use the EXISTS later
// we need to join outer and inner query here
// and that's a place for outer query ALIAS
.Where(c => c.PersonId == person.ItemId)
.Select(c => c.PersonId); // must select something...
var query = session
// ALIAS expressing the outer query in action again
.QueryOver<Person>(() => person)
.WithSubquery
.WhereExists(childCriteria)
.Future();