2009-06-22 3 views
0

У меня есть простой пример блога: столбец, таблица тегов и таблица поиска Post_Tag_MM, связывающая две таблицы.Nhibernate от многих до многих критериев запроса с подзапросом

Я использую этот запрос HQL для того, чтобы извлечь все сообщения, которые не имеют некоторые теги:

  var result = session 
          .CreateQuery(@" 
           select p from Post p 
           join p.Tags t 
           where (select count(ti) from p.Tags ti where ti.Uid in (:uidList)) = 0 
          ") 
          .SetParameterList("uidList", uidList) 
          .SetResultTransformer(new DistinctRootEntityResultTransformer()) 
          .List<Post>(); 

Как это многие-ко-многим запросы и подвыборка переведенными в запрос критерии?

Я еще не совсем понял API DetachedCriteria и не смог заставить его вернуть правильный набор результатов.

спасибо, что заранее.

С уважением,

Макс

ответ

-1

Попробуйте ниже. Предполагая, что uidList - это коллекция идентификаторов тегов.

var results = S.CreateCriteria(typeof(Post)) 
       .CreateCriteria("Tags") 
       .Add(
        Expression.Not(
        Expression.In("Uid", uidList) 
        ) 
       ) 
       .List<Post>(); 

Возможно, это более эффективный способ сделать это, хотя это сработало для меня в прошлом. Это может быть не синтаксис совершенный, но общий принцип должен заставить вас двигаться снова, надеюсь.

+0

Благодарим вас за ответ! Однако это не возвращает ожидаемый результат, и запрос, построенный из этого оператора, не включает подзапрос. – 2009-06-23 07:05:47

+0

-1 для ответа, который не включает подзапрос – ddc0660

0

Для представления подзадача вам необходимо использовать DetachedCriteria. Затем добавьте этот запрос в CreateCriteria с подзапросом.

2

Если я правильно понял вопрос, у вас есть таблица соединений, содержащая отношения PostId, TagId, называемые Post_Tag_MM, и вы хотите, чтобы все сообщения, которые НЕ имеют никаких тегов, идентифицированных коллекцией идентификаторов тегов. Затем в простой sql вы можете сделать:

выберите * из сообщений, где id не в (выберите отдельный PostId из Post_Tag_MM, где TagId в (1,2,3));

Использование API DetachedCrietria, что подзапрос будет выглядеть следующим образом, предполагая, что вы сопоставили таблицу Post_Tag_MM к классу PostTag:

var subCriteria = DetachedCriteria.For(typeof (PostTag)) 
    .SetProjection(Projections.Property("PostId")) 
    .Add(Restrictions.PropertyIn("TagId", tagIdList)); 

прикрепиться и свести на нет «свойство в» критериях подзапросов к вашим основным критериям например

var result = session.CreateCriteria.For(typeof(Post)) 
    .SetResultTransformer(new DistinctRootEntityResultTransformer()) 
    .Add(Subqueries.PropertyNotIn("Id", subCriteria)) 
    .List<Post>(); 
Смежные вопросы