如何 select NHibernate 中销量前 10 的产品?

How to select top 10 most sold products in NHibernate?

这个解决方案对我不起作用: C#/NHibernate - Get first 10 records ordered by grouped sum

我的情况非常相似,但我一直收到以下错误消息:

Additional information: could not resolve property: Produto_Id of: SistemaVendas.Domain.venda.ProdutoVendido

到目前为止我的代码:

ICriteria criteria = unitOfWork.Session
            .CreateCriteria<ProdutoVendido>("ProdutoVendido")
            .SetMaxResults(limite)
            .CreateCriteria("Produto_Id")
                .SetProjection(Projections.ProjectionList()
                    .Add(Projections.GroupProperty("Produto_Id"), "ID")
                    .Add(Projections.Sum("ProdutoVendido.Quantidade"), "QuantitySum")
                )
                .AddOrder(Order.Desc("QuantitySum"));

return criteria
            .SetResultTransformer(Transformers.AliasToBean<Produto>())
            .List<Produto>().ToList();

我做错了什么?

P.S。 ProdutoVendido = SoldProduct 和 Produto = Product

ProdutoVendido 映射

    public ProdutoVendidoMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();            

        Map(x => x.Quantidade);
        Map(x => x.Desconto);
        Map(x => x.Observacao).Length(ProdutoVendido.MAX_OBSERVACAO_LENGTH);            

        References(x => x.Venda)
            .Cascade.None();
        References(x => x.Produto)
            .Cascade.None();
    }

编辑:

最终解决方案

正如@Radim Köhler 指出的那样,我刚刚创建了这个 DTO

public class ProdutoDto
{
    public ulong Id { get; set; }
    public int QuantidadeTotal { get; set; }
}

我最后的 NHibernate 查询是

ICriteria criteria = unitOfWork.Session
    .CreateCriteria<ProdutoVendido>("ProdutoVendido")
    .SetMaxResults(limite)            
    .CreateCriteria("Produto", "p")            
        .SetProjection(Projections.ProjectionList()
            .Add(Projections.GroupProperty("p.Id"), "Id")
            .Add(Projections.Sum("ProdutoVendido.Quantidade"), "QuantidadeTotal")                    
        )
        .AddOrder(Order.Desc("QuantidadeTotal"));

var ids = criteria
            .SetResultTransformer(Transformers.AliasToBean<ProdutoDto>())
            .List<ProdutoDto>();

return unitOfWork.Session
    .CreateCriteria<Produto>()                
    .Add(Restrictions.In("Id", ids.Select(x => x.Id).ToArray()))
    .List<Produto>().ToList();

要修复 NHibernate 返回的错误,我们必须查询现有的对象模型。在这种情况下,销售的产品 (ProdutoVendido) 引用 Produto,而不是 Produto_Id

...
Session
  .CreateCriteria<ProdutoVendido>("ProdutoVendido")
  ...
  // this line is about joining reference
  // not the column
  //.CreateCriteria("Produto_Id")
  .CreateCriteria("Produto", "p") // "p" is now alias which we can use

检查类似的工作查询,例如here

延长

我们需要能够投影 SUM 属性 - 是一个 DTO (不是 POCO, just DTO for this purpose). Check this Q & A for inspiration Joining two tables with specific columns in nhibernate

这可能是:

public class ProdutoDto
{
    public virtual int ID { get; set; }
    public virtual decimal QuantitySum { get; set; } // the type should match
}

我们可以将其用作投影目标:

return criteria
        .SetResultTransformer(Transformers.AliasToBean<ProdutoDto>())
        .List<ProdutoDto>().ToList();