2012-10-18 117 views
2

嗯,基本上我试图找出一种方法来获得10个最畅销的产品。东西我可以很容易地用下面的SQL查询实现:C#/ NHibernate - 获取前10条记录按分组总数排序

SELECT `product`.* 
FROM `product` 
INNER JOIN `sale_item` ON `product`.`id` = `sale_item`.`product_id` 
GROUP BY `product`.`id` 
ORDER BY SUM(`sale_item`.`quantity`) DESC 
LIMIT 10; 

我与NHibernate的成功最接近的,我相信是这样的:

ICriteria criteria = NHibernateSession 
    .CreateCriteria<SaleItem>("SaleItem") 
    .SetMaxResults(10) 
    .CreateCriteria("ID.Product") 
     .SetProjection(Projections.ProjectionList() 
      .Add(Projections.GroupProperty("ID.Product")) 
      .Add(Projections.Sum("SaleItem.Quantity"), "QuantitySum") 
     ) 
     .AddOrder(Order.Desc("QuantitySum")); 

List<Product> l = criteria 
    .List<Product>() as List<Product>; 

即生成以下SQL(非常类似地雷) :

SELECT this_.product_id AS y0_, 
     sum(this_.quantity) AS y1_ 
FROM sale_item this_ 
INNER JOIN product product1_ ON this_.product_id=product1_.id 
GROUP BY this_.product_id 
ORDER BY y1_ DESC LIMIT 10; 

不幸的是,它在执行查询时失败。我很确定这跟我做.CreateCriteria<SaleItem>有什么关系,然后问.List<Product>,但我不知道如何以其他方式做到这一点。

任何帮助深表谢意。

回答

3

您可以使用Transformers.AliasToBean<Product>()结果变压器:

ICriteria criteria = NHibernateSession 
    .CreateCriteria<SaleItem>("SaleItem") 
    .SetMaxResults(10) 
    .CreateCriteria("ID.Product") 
     .SetProjection(Projections.ProjectionList() 
      .Add(Projections.GroupProperty("ID.Product"), "ID") 
      .Add(..., "...") // another Product property 
      .Add(Projections.Sum("SaleItem.Quantity"), "QuantitySum") 
     ) 
     .AddOrder(Order.Desc("QuantitySum")); 

List<Product> l = criteria 
    .SetResultTransformer(Transformers.AliasToBean<Product>()); 
    .List<Product>() as List<Product>; 
1

您正在投影数据,因此您没有从数据库中获取Product(或SaleItem)。您需要使用非泛型List()来获取对象列表。这些对象将是对象数组,其元素与投影值相对应。

要一次性获得整个产品,必须将该查询保留在子查询中,其中外部查询将返回由子查询识别的产品的完整产品数据。