Вопрос о критериях NHibernate - PullRequest
0 голосов
/ 16 мая 2010

У меня есть объект person, который может иметь неограниченное количество имен. Так что первые имена - это еще один объект.

е

человек --- имя
--- имя
--- имя

То, что я хочу сделать, это написать запрос nhiberate, с помощью которого я получу человека с определенными именами.

поэтому одним запросом может быть поиск кого-то, чьи имена - Элисон, Джейн и Филиппа, тогда следующим запросом может быть поиск кого-то, чьи имена - Элисон и Джейн.

Я только хочу вернуть людей, у которых есть все имена, по которым я ищу. Пока у меня есть

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 ]

1 голос
/ 17 мая 2010

Разве это не должно быть И-выражением?

Как это:

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

EDIT

Ok. Чтобы соответствовать приведенному выше запросу, с небольшим изменением, чтобы избежать объединения:

    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"))));
    }

Для этого необходимо иметь сопоставленное свойство с именем Person в классе Name.

0 голосов
/ 17 мая 2010

Это тот тип 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%'
) 
0 голосов
/ 17 мая 2010

Есть разные способы сделать это. Вы можете использовать существующий подзапрос для каждого имени. Или вы можете присоединиться к именам, добавить name like '%blah%' для каждого имени, группировать по человеку и добавить having count(*) = nameCnt. Однако предложение «Наличие» не поддерживается в ICriteria, поэтому вам нужно использовать HQL.

...