I'm just starting out with NHibernate and I'm having trouble with running more complex queries.
I have entities with a list of tags attached. The user will provide two lists of tags, include and exclude.
I need to find all the entities that have all of the include tags, and exclude any entites that have any tag in the exclude list.
Below is my first effort- which is clearly wrong as its listing all Display objects that have any of the include tags rather than all!
Any assistance is greatly 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();
That query isn't trivial (have a think about how you might do this using raw SQL). I think the following will work (requiring two correlated sub-queries):
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With