2012-12-21 74 views
1

我有一個對象模型,其中Order包含許多LineItems,並且每個LineItem都有一個關聯的Product。在對象模型中,這些是單向關聯 - 一個LineItem不知道任何關於它的Order如何使用NHibernate的QueryOver API表示包含WHERE..IN子查詢的查詢?

Class diagram

我想查詢包含與產品名稱匹配的字符串行項目的訂單,每個訂單(以便能夠進行分頁)返回一行。

SELECT * FROM Orders 
WHERE OrderID IN (
    SELECT DISTINCT OrderID 
    FROM LineItems 
    INNER JOIN Products on LineItems.ProductID = Products.ProductID 
    WHERE Products.Name = 'foo' 
) 

假設我有一個ICriteria或代表的子查詢的IQueryOver,實際上,我怎麼把它應用到我的根訂單查詢?

var subquery = QueryOver.Of<LineItem> 
         .Where(l => l.Product.Name == "foo") 
         .TransformUsing(Transformers.DistinctRootEntity); 

我發現很多類似的假設在查詢中的根對象的例子是對一個一對多關係的「多」的一面,但我無法弄清楚如何添加限制在根對象有很多

+0

嘗試使用WithSubquery.WhereProperty – frictionlesspulley

+0

如果LineItem的沒有秩序的屬性。那麼你是如何在你的示例SQL中投射出OrderId的? – frictionlesspulley

回答

2

我會讓它秩序之間的雙向關係,訂單項以允許有效查詢(減少所需的連接數)。但是,如果出於某種奇怪的原因,你不能,你需要從訂單開始子查詢...

LineItem lineItemAlias = null; 
Product productAlias = null; 

var subQuery = QueryOver.Of<Order>() 
      .JoinAlias(x => x.LineItems,() => lineItemAlias) 
      .JoinAlias(() => lineItemAlias.Product,() => productAlias) 
      .Where(() => productAlias.Name == "foo") 
      .Select(Projections.Group<Order>(x => x.Id)); 

var results = Session.QueryOver<Order>() 
       .WithSubquery.WhereProperty(x => x.Id).In(subQuery) 
       .List(); 
2

您提供可以使用此

var subQuery = 
     QueryOver.Of<LineItem>(() => lineItem) 
      .JoinAlias(() => lineItem.Products,() => product) 
      .Where(() => product.Name == "foo") 
      .Select(Projections.Distinct(
         Projections.Property(()=> lineItem.Order.Id)));; 

var theQueryYouNeed = 
       QueryOver.Of<Orders>(() => order) 
       .WithSubquery.WherePropertyIn(() => order.Id).In(subQuery); 

但是,如果你LineItem實體沒有Order房產,那麼你真的不能使用子查詢來達到的在SQL的直接翻譯。

如果你需要找到

所有訂單,其具有的LineItem其中產品名稱是「富」,那麼

var theQueryYouNeed = 
    QueryOver.Of<Orders>(() => order) 
    .JoinAlias(() => order.LineItems,() => lineItem) 
    .JoinAlias(() => lineItem.Product,() => product) 
    .Where(() => product.Name == "foo") 
    .TransformUsing(new DistinctRootEntityResultTransformer()) 
+0

您可能需要上的子查詢添加限制正常工作,因爲我不知道確切的關係姓名的LineItem ..你得到的總體思路 – frictionlesspulley

+0

的問題是,我的'LineItem's沒有一個'Order'財產,所以沒有辦法在我的子查詢中表示我需要OrderID。我可以通過混合QueryOver和ICriteria來做到這一點嗎? –

+0

我寫的QueryOver是通過看哪裏的OrderId定義您發佈的SQL ..(上實體)在內部SQL在你的榜樣 – frictionlesspulley

相關問題