2012-10-18 124 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()來獲取對象列表。這些對象將是對象數組,其元素與投影值相對應。

要一次性獲得整個產品,必須將該查詢保留在子查詢中,其中外部查詢將返回由子查詢識別的產品的完整產品數據。