好的,长时间听众,第一次来电。
我尝试使用QueryOver API编写查询,该API将在我的实体的某些属性中搜索多个术语。问题是其中一些属性是对另一个实体的引用;但是,我仍然需要在该引用的属性中搜索给定的术语。
我希望能够编写类似下面代码的内容。在下面的代码中,FirstName,MiddleName和LastName都是Person实体的基本字符串属性。 Department属性是Department类型的参考属性。 Department实体有三个属性:Id,Value,Description。还必须在Person.Department.Value中搜索给定的术语以及基本属性。
var queryOver = session.QueryOver<Person>();
foreach (string term in searchTerms)
{
queryOver = queryOver.Where(Restrictions.On<Person>(x => x.FirstName).IsInsensitiveLike(term, MatchMode.Anywhere) ||
Restrictions.On<Person>(x => x.LastName).IsInsensitiveLike(term, MatchMode.Anywhere) ||
Restrictions.On<Person>(x => x.MiddleName).IsInsensitiveLike(term, MatchMode.Anywhere) ||
//This following line doesn't work.
Restrictions.On<Person>(x => x.Department.Value).IsInsensitiveLike(term, MatchMode.Anywhere)
}
我尝试过使用别名并使用NHibernate.Linq / Query API。我知道我需要使用别名进行某种联接,但我想我并不理解我读过的所有问题/文章。他们中的大多数人似乎都在讨论对Reference或Child进行查询/子查询,但我遇到了将这些查询与其他属性一起翻译成查询并将它们全部OR化的问题。
最终的SQL I&#m; m射击是这样的:
SELECT *
FROM `persons`
WHERE (`FirstName` LIKE '%term1%' OR
`LastName` LIKE '%term1%' OR
`MiddleName` LIKE '%term1%' OR
`Department`.`Value` LIKE '%term1%') AND //I know this won't work
(`FirstName` LIKE '%term2%' OR
`LastName` LIKE '%term2%' OR
`MiddleName` LIKE '%term2%' OR
`Department`.`Value` LIKE '%term2%') AND etc...
最后,非常感谢您提前寻求帮助。如果您认为我可以使用不同的查询获得相同的结果,我可以在NHibernate中使用不同的API,甚至可以使用不同的搜索策略。
答案 0 :(得分:0)
好吧,我终于明白了。感谢这些帖子指出我正确的方向:
Filtering and projecting an association using NHibernate QueryOver
这是我提出的做我需要的代码。我真的不想使用随机变量设置为null的丑陋别名,我也不想在其他地方定义一堆不同的查询。如果有人需要,我可以进一步解释。
var persons = session.QueryOver<Person>()
.Where(Restrictions.Disjunction()
.Add(Subqueries.WhereProperty<Person>(x => x.Department.Id).In(QueryOver.Of<Department>().WhereRestrictionOn(x => x.Value).IsInsensitiveLike("somedep", MatchMode.Anywhere).Select(x => x.Id)))
.Add<Person>(x => x.LastName.IsInsensitiveLike("somedep", MatchMode.Anywhere)))
.Where(Restrictions.Disjunction()
.Add(Subqueries.WhereProperty<Person>(x => x.Department.Id).In(QueryOver.Of<Department>().WhereRestrictionOn(x => x.Value).IsInsensitiveLike("myname", MatchMode.Anywhere).Select(x => x.Id)))
.Add<Person>(x => x.LastName.IsInsensitiveLike("myname", MatchMode.Anywhere))))
.List();