queryover - 在同一析取中使用 属性 和 属性 引用的 QueryOver

queryover - QueryOver with Property and Property of Reference in Same Disjunction

好的,长期听众,第一次来电。

我正在尝试使用 QueryOver 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。我知道我需要使用别名进行某种连接,但我想我并不理解我读过的所有 questions/articles。他们中的大多数人似乎都在谈论对引用或子对象执行 query/subquery,但我在将这些查询与其他属性一起转换为查询并将它们全部组合在一起时遇到了问题。

我要拍摄的决赛 SQL 是这样的:

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 甚至不同的搜索策略。

好吧,我终于明白了。感谢这些帖子为我指明了正确的方向:

QueryOver Or with Subquery

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();