NHibernate Criteria问题

时间:2010-05-16 19:51:31

标签: nhibernate icriteria

我有一个人物对象,可以拥有无​​限数量的名字。所以名字是另一个对象。

人---姓名
---名字
---名字

我想要做的是编写一个禁止查询,使用该查询会得到一个具有某些名字的人。

因此,一个查询可能会找到名字为alison,jane和philippa的人,然后下一个查询可能会找到一个名字为alison and jane的人。

我只想归还拥有我所搜索的所有名字的人。到目前为止我已经

ICriteria criteria = session.CreateCriteria(typeof (Person));
criteria.CreateAlias("Names", "name");
ICriterion expression = null;
foreach (string name in namesToFind)
{
    if (expression == null)
    {
        expression = Expression.Like("name.Value", "%" + name + "%");
    }
    else
    {
        expression = Expression.Or(
            expression,
            Expression.Like("name.Value", "%" + name + "%"));
    }
}

if (expression != null)
    criteria.Add(expression);

但这会让每个人都找到我正在搜索的名字,而不是所有的名字。

任何人都可以帮我解决这个问题吗?谢谢!

3 个答案:

答案 0 :(得分:1)

那么它不应该是一个AND表达吗?

像这样:

    ICriteria criteria = session.CreateCriteria(typeof (Person));
    criteria.CreateAlias("Names", "name");
    foreach (string name in namesToFind)
    {
        criteria.Add(Expression.Like("name.Value", "%" + name + "%"));
    }

修改

确定。要匹配您在上面提供的查询,请稍加更改以避免加入:

    ICriteria criteria = s.CreateCriteria(typeof(Person));
    foreach (string name in namesToFind)
    {
        criteria.Add(Subqueries.PropertyIn("Id",
            DetachedCriteria.For<Name>()
                .Add(Restrictions.Like("Value", name, MatchMode.Anywhere))
                .SetProjection(Projections.Property("Person"))));
    }

这要求您在Name类上有一个名为Person的映射属性。

答案 1 :(得分:0)

有多种方法可以做到这一点。您可以为每个名称使用exists子查询。或者,您可以加入名称,为每个名称添加name like '%blah%',逐个添加having count(*) = nameCnt。但是,ICriteria不支持Having子句,因此您需要使用HQL。

答案 2 :(得分:0)

这是我想要获得的那种sql:

select * from person where Id in
(
select person.id from person inner join [name]
on person.id = name.personId
 where name.value like '%jane%'
)
and id in
(
select person.id from person inner join [name]
on person.id = name.personId
 where name.value like '%janice%'
) 
and id in
(
select person.id from person inner join [name]
on person.id = name.personId
 where name.value like '%louise%'
)