Я только начинаю с NHibernate, и я испытываю затруднения выполнить более сложные запросы.
У меня есть объекты со списком присоединенных тегов. Пользователь будет предоставлять два списка тегов, включать и исключать.
Я должен найти все объекты, которые имеют все включать теги и исключают любые объекты, которые имеют любой тег в исключить списке.
Ниже мое первое усилие - который является явно неправильным как его список всех Экранных объектов, которые имеют любой из включать тегов, а не всех!
Любая помощь значительно appeciated.
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();
Этот запрос нетривиален (подумайте, как это можно сделать, используя необработанный 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();