2011-10-31 15 views
22

ihave la siguiente consulta NHibernate usando una subconsulta:QueryOver O con subconsulta

NHContext.Session.QueryOver<Item>() 
      .WithSubquery.WhereProperty(x => x.ItemId).In(QueryOver.Of<Foo>().Where(x => x.AFlag).Select(x => x.ItemId)) 
      .WithSubquery.WhereProperty(x => x.ItemId).In(QueryOver.Of<Bar>().Where(x => x.AFlag).Select(x => x.Item)) 
      .Future<Item>(); 

Esto ejecuta el siguiente código SQL:

SELECT * 
FROM item this_ 
WHERE this_.ItemId in (SELECT this_0_.ItemId as y0_ 
          FROM Foo this_0_ 
          WHERE this_0_.AFlag = 1 /* @p0 */) 
and this_.ItemId in (SELECT this_0_.ItemId as y0_ 
          FROM Bar this_0_ 
          WHERE this_0_.AFlag = 1 /* @p0 */) 

me gustaría que utilice O así por ejemplo:

SELECT * 
FROM item this_ 
WHERE this_.ItemId in (SELECT this_0_.ItemId as y0_ 
          FROM Foo this_0_ 
          WHERE this_0_.AFlag = 1 /* @p0 */) 
or this_.ItemId in (SELECT this_0_.ItemId as y0_ 
          FROM Bar this_0_ 
          WHERE this_0_.AFlag = 1 /* @p0 */) 

Sé que puedo hacerlo en Criteria haciendo algo como:

var disjunction = new Disjunction(); 
disjunction.Add(Subqueries.PropertyIn("ItemId", 
    DetachedCriteria.For<Foo>() 
    .SetProjection(Projections.Property("ItemId")) 
    .Add(Restrictions.Eq("AFlag", 1)) 
)); 

Pero se preguntaba si había una manera más fácil de hacerlo a través de QueryOver, y evitar el uso de cadenas para los nombres de las propiedades.

Gracias por cualquier ayuda.

Respuesta

36

Para la disyunción menos común (o) Creo que es necesario utilizar el Subqueries.WhereProperty<> en lugar de WithSubquery

Session.QueryOver<Item>() 
    .Where(Restrictions.Disjunction() 
     .Add(Subqueries.WhereProperty<Item>(x => x.ItemId).In(QueryOver.Of<Foo>().Where(x => x.AFlag).Select(x => x.ItemId))) 
     .Add(Subqueries.WhereProperty<Item>(x => x.ItemId).In(QueryOver.Of<Bar>().Where(x => x.AFlag).Select(x => x.Item)))) 
    .Future<Item>(); 
Cuestiones relacionadas