2

我有一个对象模型,其中一个Order包含许多LineItems,每个LineItem都有一个关联的Product. 在对象模型中,这些是单向关联LineItem——a 不知道任何关于它的Order.

类图

我想查询包含产品名称与字符串匹配的订单项的订单,为每个订单返回一行(以便可以执行分页)。

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

我找到了很多假设查询中的根对象位于一对多关系的“多”端的示例,但我不知道如何对根对象的某些内容添加限制许多.

4

2 回答 2

3

我将使其成为订单和订单项之间的双向关系,以实现高效查询(减少所需的连接数量)。但是,如果由于某种奇怪的原因你不能,你需要从 Order 开始子查询......

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();
于 2013-01-02T21:22:50.527 回答
2

您提供的 SQL 的直接翻译可以使用这个来实现

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属性,那么您就不能真正使用子查询。

如果需要找

所有具有产品名称为“foo”的 LineItem 的订单

var theQueryYouNeed = 
  QueryOver.Of<Orders>(() => order)
     .JoinAlias(() => order.LineItems, () => lineItem)
     .JoinAlias(() => lineItem.Product, () => product)
     .Where(() => product.Name == "foo")
     .TransformUsing(new DistinctRootEntityResultTransformer())
于 2012-12-21T18:29:31.897 回答