Nhibernate запрос многие ко многим критериям с подвыбором - PullRequest
0 голосов
/ 22 июня 2009

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

Я использую этот 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 и не могу заставить его вернуть правильный набор результатов.

Заранее большое спасибо.

С уважением,

Макс

Ответы [ 3 ]

2 голосов
/ 16 апреля 2010

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

выберите * из сообщений, в которых идентификатор не указан (выберите отдельный 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));

присоедините и отмените критерии подзапроса 'property in' к вашим основным критериям, как это

var result = session.CreateCriteria.For(typeof(Post))
    .SetResultTransformer(new DistinctRootEntityResultTransformer())
    .Add(Subqueries.PropertyNotIn("Id", subCriteria))
    .List<Post>();
0 голосов
/ 15 апреля 2010

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

0 голосов
/ 22 июня 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...