2010-06-02 7 views
7

Ich beginne gerade mit NHibernate und ich habe Probleme mit komplexeren Abfragen.NHibernate: QueryOver <> help

Ich habe Entitäten mit einer Liste von Tags angehängt. Der Benutzer wird zwei Listen von Tags bereitstellen, ein- und ausschließen.

Ich muss alle Entitäten finden, die alle Include-Tags enthalten, und alle Entitäten ausschließen, die ein Tag in der Ausschlussliste enthalten.

Unten ist meine erste Bemühung - was eindeutig falsch ist, da es alle Anzeigeobjekte auflistet, die eines der Include-Tags haben und nicht alle!

Jede Hilfe ist sehr hilfreich.

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(); 

Antwort

14

Diese Abfrage ist nicht trivial (denken Sie darüber nach, wie Sie dies mit Raw SQL machen könnten). Ich denke, das folgende funktioniert (erfordert zwei korrelierte Unterabfragen):


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(); 
+6

Danke für Ihre Hilfe, ich werde es versuchen. Ich finde viele der Beispiele sind nicht komplex genug für reale Anwendungen. Danke noch einmal –

Verwandte Themen