2010-06-02 5 views
7

Je commence tout juste avec NHibernate et j'ai des problèmes avec des requêtes plus complexes.NHibernate: QueryOver <> help

J'ai des entités avec une liste d'étiquettes attachées. L'utilisateur fournira deux listes d'étiquettes, inclure et exclure.

Je dois trouver toutes les entités qui ont toutes les balises d'inclusion, et exclure tous les entites qui ont des balises dans la liste d'exclusion.

Ci-dessous est mon premier effort - ce qui est clairement faux que sa liste de tous les objets d'affichage qui ont l'une des balises d'inclusion plutôt que de tous!

Toute assistance est grandement appréciée.

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

Répondre

14

Cette requête n'est pas triviale (pensez à la façon dont vous pourriez le faire en utilisant SQL brut). Je pense que ce qui suit fonctionnera (nécessitant deux sous-requêtes corrélées):


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

Merci pour votre aide, je vais essayer. Je trouve que beaucoup d'exemples ne sont pas assez complexes pour des applications réelles. Merci encore –

Questions connexes