2010-06-02 21 views
7

Estoy empezando con NHibernate y tengo problemas para ejecutar consultas más complejas.NHibernate: QueryOver <> help

Tengo entidades con una lista de etiquetas adjuntas. El usuario proporcionará dos listas de etiquetas, incluir y excluir.

Necesito encontrar todas las entidades que tienen todas las etiquetas de inclusión, y excluyo cualquier entidad que tenga una etiqueta en la lista de exclusión.

A continuación se muestra mi primer esfuerzo, lo que es claramente incorrecto ya que enumera todos los objetos de visualización que tienen alguna de las etiquetas de inclusión en lugar de todas.

Cualquier ayuda es muy apreciada.

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

Respuesta

14

Esa consulta no es trivial (piense cómo puede hacerlo con SQL sin formato). Creo que lo siguiente funcionará (requiere dos subconsultas correlacionadas):


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

Gracias por su ayuda, lo intentaré. Estoy encontrando que muchos de los ejemplos no son lo suficientemente complejos para las aplicaciones del mundo real. Gracias de nuevo –

Cuestiones relacionadas