2011-10-31 107 views
22

IHAVE以下NHibernate的查詢中使用子查詢:QueryOver或者與子查詢

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

這將運行以下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 */) 

我想它使用OR因此,例如:

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 */) 

我知道我可以在Criteria中做這樣的事情:

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

但想知道是否有更簡單的方法來通過QueryOver做到這一點,並避免使用字符串的屬性名稱。

感謝您的任何幫助。

回答

36

對於不常見或(or),我認爲你需要使用,而不是Subqueries.WhereProperty<>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>();