NHibernate: QueryOver <> помощь - PullRequest
7 голосов
/ 02 июня 2010

Я только начинаю с NHibernate, и у меня возникают проблемы с выполнением более сложных запросов.

У меня есть объекты со списком прикрепленных тегов. Пользователь предоставит два списка тегов, include и exclude.

Мне нужно найти все объекты, которые имеют все теги включения, и исключить любые объекты, у которых есть какой-либо тег в списке исключений.

Ниже мое первое усилие, которое явно неверно, поскольку в нем перечислены все экранные объекты, имеющие какой-либо из тегов включения, а не все!

Любая помощь очень важна.

var includeTagIds = (from tag in regime.IncludeTags select tag.Id).ToList<int>();
var excludeTagIds = from tag in regime.ExcludeTags select tag.Id;


var displays = session.QueryOver<Display>()
                      .JoinQueryOver<DisplayTag>(display => display.Tags)
                      .WhereRestrictionOn(tag => tag.Id)
                      .IsIn(includeTagIds).List().Distinct();


return displays.ToList();

1 Ответ

14 голосов
/ 03 июня 2010

Этот запрос не тривиален (подумайте о том, как вы могли бы сделать это, используя сырой SQL). Я думаю, что будет работать следующее (требуются два коррелированных подзапроса):


Display displayAlias = null;

var countIncludedTagsSubquery =
    QueryOver.Of<Display>()
        .Where(d => d.Id == displayAlias.Id)
        .JoinQueryOver<DisplayTag>(d => d.Tags)
            .WhereRestrictionOn(t => t.Id).IsInG(includedTagIds)
            .Select(Projections.RowCount());

var excludedTagsSubquery =
    QueryOver.Of<Display>()
        .Where(d => d.Id == displayAlias.Id)
        .JoinQueryOver<DisplayTag>(d => d.Tags)
            .WhereRestrictionOn(t => t.Id).IsInG(excludedTagIds)
            .Select(t => t.Id);

var displays =
    session.QueryOver<Display>(() => displayAlias)
        .WithSubquery.WhereValue(includedTagIds.Count).Eq(countIncludedTagsSubquery)
        .WithSubquery.WhereNotExists(excludedTagsSubquery)
        .List();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...