2011-10-31 36 views
22

ihave truy vấn NHibernate sau sử dụng một subquery:QueryOver Hoặc với Subquery

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

này chạy SQL sau đây:

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

Tôi muốn nó để sử dụng HOẶC để ví dụ:

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

Tôi biết tôi có thể làm điều đó trong Tiêu chí bằng cách thực hiện một việc như:

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

Nhưng đã tự hỏi liệu có cách nào dễ dàng hơn để làm điều đó thông qua QueryOver và tránh sử dụng chuỗi cho tên thuộc tính.

Cảm ơn bạn đã được trợ giúp.

Trả lời

36

Đối với phân ly ít phổ biến (hoặc) Tôi nghĩ rằng bạn cần phải sử dụng Subqueries.WhereProperty<> thay vì 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>();