none
SELECT com JOINS, GROUP BY e SUM no Entity Framework RRS feed

  • Pergunta

  • Olá pessoal,

    Tenho esse select que funciona certinho no SQL:

     

    SELECT produto.descricao, grupoProduto.nome AS grupo, sum(quantidade) AS quantidade, sum(valor) AS total 
    from pedidoProdutos
      inner join produto on produto.idProduto = pedidoProdutos.idProduto 
      inner join grupoProduto on produto.idGrupoProduto = grupoProduto.idGrupoProduto 
    group by pedidoProdutos.idProduto
    order by quantidade desc 
    

     

    Basicamente ele retorna os produtos mais vendidos, por ordem de quantidade decrescente, agrupado pelo produto...

    Tentei fazer a conversão do select acima para o EF... mas sem sucesso. A seleção é executada sem erros, porém, não está agrupando nem totalizando a quantidade dos produtos corretamente. Abaixo o código que consegui montar após muita pesquisa na net (não encontrei nenhum exemplo semelhante ao meu caso):

     

    var produtos = from prodPedido in ctx.pedidoProdutos
            join prod in ctx.produto on prodPedido.idProduto equals prod.idProduto
            join pedidos in ctx.pedido on prodPedido.idPedido equals pedidos.idPedido
            where pedidos.data >= dataInicial && pedidos.data <= dataFinal
            group prodPedido by new
            {
             prodPedido.idProduto,
             prodPedido.produto.idGrupoProduto,
             prodPedido.produto.descricao,
             grupo = prodPedido.produto.grupoProduto.nome,
             prodPedido.quantidade,
             prodPedido.valor
            } into g
            orderby g.Sum(s => s.quantidade) descending
            select new
            {
             g.Key.idGrupoProduto,
             g.Key.idProduto,
             g.Key.descricao,
             g.Key.grupo,
             quantidade = g.Sum(s => s.quantidade),
             total = g.Sum(t => t.valor)
            };
    

    Alguém já precisou fazer algo semelhante e pode me dar uma dica do que fiz errado?

    Abraços a todos


    Wagner Samuel de Oliveira
    WSO Software
    www.wso.com.br
    quinta-feira, 14 de abril de 2011 05:15

Respostas

  • Olá Wagner,

    A query LINQ para o SELECT que você postou no início do tópico ficaria assim:

    var resultado = from ped in pedidoProdutos
            join prod in produto on ped.idProduto equals prod.idProduto
            join grupoProd in grupoProduto on prod.idGrupoProduto equals grupoProd.idGrupoProduto
            group ped by new 
            {
              prod.descricao,
              grupoProd.nome
            } into g
            orderby g.Sum(p => p.quantidade) descending
            select new 
            {
              Descricao = g.Key.descricao,
              Nome = g.Key.nome,
              SomaQuantidade = g.Sum(p => p.quantidade),
              SomaValor = g.Sum(p => p.valor)
            };
    
    

    André Alves de Lima
    Microsoft MVP - Client App Dev
    Visite o meu site: http://www.andrealveslima.com.br
    Me siga no Twitter: @andrealveslima
    quinta-feira, 14 de abril de 2011 11:38
    Moderador

Todas as Respostas

  • Olá Wagner,

    A query LINQ para o SELECT que você postou no início do tópico ficaria assim:

    var resultado = from ped in pedidoProdutos
            join prod in produto on ped.idProduto equals prod.idProduto
            join grupoProd in grupoProduto on prod.idGrupoProduto equals grupoProd.idGrupoProduto
            group ped by new 
            {
              prod.descricao,
              grupoProd.nome
            } into g
            orderby g.Sum(p => p.quantidade) descending
            select new 
            {
              Descricao = g.Key.descricao,
              Nome = g.Key.nome,
              SomaQuantidade = g.Sum(p => p.quantidade),
              SomaValor = g.Sum(p => p.valor)
            };
    
    

    André Alves de Lima
    Microsoft MVP - Client App Dev
    Visite o meu site: http://www.andrealveslima.com.br
    Me siga no Twitter: @andrealveslima
    quinta-feira, 14 de abril de 2011 11:38
    Moderador
  • Valeu André!!

    Funcionou perfeitamente... agora se não for abusar de ti poderia me dar mais uma dica?

    No SELECT são selecionados todos os grupos de produtos... como eu posso fazer na instrução para selecionar apenas um determinado grupo? Detalhe: digamos que se eu selecionar um grupo para filtrar, existirá uma variável com o código do mesmo... se não foi selecionado nenhum grupo essa variável terá valor ZERO... ou seja, a seleção deve ser dinâmica...

    Tentei montar isso diretamente na instrução mas não consegui... então tentei filtrar o resultado do SELECT posteriormente:

     

    // Se informou um grupo de produto filtra
    if (!grupoSelecionado.Equals(0))
     produtos.Where(g => g.idGrupoProduto == grupoSelecionado);
    

     

    Mas não obtive sucesso :(

     

    Abraço


    Wagner Samuel de Oliveira
    WSO Software
    www.wso.com.br

    quinta-feira, 14 de abril de 2011 14:34
  • Wagner,

    Ué... Era pra ter funcionado do jeito que você fez... Ele retornou todos os valores?

    Lembrando que o Where retorna um novo resultado que deve ser armazenado em uma variável e aí então utilizado:

    var resultadoFiltrado = produtos.Where(g => g.IdGrupoProduto == grupoSelecionado);


    André Alves de Lima
    Microsoft MVP - Client App Dev
    Visite o meu site: http://www.andrealveslima.com.br
    Me siga no Twitter: @andrealveslima
    quinta-feira, 14 de abril de 2011 16:12
    Moderador
  • Olá André,

    Eu não estava jogando o novo resultado em uma nova variável... achei que ele faria o filtro no já existente.

    Valeu de novo!

    Abraço


    Wagner Samuel de Oliveira
    WSO Software
    www.wso.com.br
    quinta-feira, 14 de abril de 2011 19:14