2012-12-21 53 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

相关问题