【问题标题】:How to select top 10 most sold products in NHibernate?如何选择 NHibernate 中销量最高的 10 款产品?
【发布时间】:2016-05-09 19:20:12
【问题描述】:

这个解决方案对我不起作用: 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 = 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();

【问题讨论】:

    标签: c# nhibernate fluent-nhibernate nhibernate-criteria


    【解决方案1】:

    要修复 NHibernate 返回的错误,我们必须查询现有的 Object 模型。在这种情况下,售出的产品 (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。查看此问答以获取灵感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();
    

    【讨论】:

    • 我更改了它,但现在它返回给我:附加信息:在“SistemaVendas.Domain.produto.Produto”类中找不到属性“QuantitySum”的设置器。我需要 QuantitySum 来订购并选择前 10 名,如何解决这个问题?
    • 我们需要的是 DTO。这将创建一个将投影映射到实体的层...我扩展了答案,希望对您有所帮助
    猜你喜欢
    • 2017-07-21
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多