如何在NHibernate中选择销售最多的前10个产品?

3
这个解决方案对我没有用: 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();

我做错了什么?

附注:ProdutoVendido = 已售出的产品,Produto = 产品

已售出的产品映射

    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();
1个回答

0
为了解决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

检查类似的工作查询,例如这里

扩展

我们需要能够投影SUM属性的DTO (不是POCO,只是DTO。 查看此Q&A以获取灵感在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();

我进行了更改,但现在它返回给我:附加信息:在类'SistemaVendas.Domain.produto.Produto'中找不到属性'QuantitySum'的设置器。我需要QuantitySum来排序并选择前10个,如何修复? - Latrova
1
我们需要的是DTO。这将创建一个将投影映射到实体的层...我扩展了答案,希望能有所帮助。 - Radim Köhler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接