How to avoid the sum of items in my lambda. Result is not as expected

3

I have this lambda:

[Route("getliberaitens/{id}")]
        public List<LiberacaoItensDTO> GetLibItems(double id)
        {
            var lista = contexto.Liberacoes
                .Join
                (
                    contexto.ItensLibs,
                    t1 => t1.IdOrcamento,
                    t2 => t2.IdOrcamento,
                    (t1, t2) => new { t1, t2 }
                )
                .Where(a => a.t1.IdOrcamento == a.t2.IdOrcamento && a.t1.IdOrcamento == id)
                .GroupBy(gb => new { gb.t1.IdOrcamento })
                .Select(item => new LiberacaoItensDTO
                {
                    TotalVenda = item.Sum(a => a.t1.TotalLiquido),
                    TotalLucro = item.Sum(a => a.t2.Total - (a.t2.Qtde * a.t2.Custo))
                }).ToList();

            //double totallucro = lista.Sum(t => t.TotalLucro);
            lista.ForEach(t => t.TotalLucro = double.Parse(string.Format(new CultureInfo("pt-BR"), "{0:N}", t.TotalLucro)));

            return lista;
        }

This is the result of Postman

"TotalVenda": 5470,
"TotalLucro": 273.71

It turns out that this result is wrong. For this budget TotalVenda is: 1094 . It arrived at this result, because in Sum, it added by the amount of items, that in this case this sale has 5 items. If I take out the Sum it gives error in t1 and t2. The total profit in this case is 30% of the total of the sale, which does not give the value above. Can someone give me some help on how to solve the SUM question?

    
asked by anonymous 20.10.2017 / 12:07

2 answers

0

As I I said in the previous question all this would depend on the logic and its data.

From what I understand you can have several elements in the group, but they all seem to have similar (or even equal) data, and then you only want one of them. You can use FirstOrDefault

var lista = contexto.Liberacoes
    .Join
    (
        contexto.ItensLibs,
        t1 => t1.IdOrcamento,
        t2 => t2.IdOrcamento,
        (t1, t2) => new { t1, t2 }
    )                
    .Where(a => a.t1.IdOrcamento == a.t2.IdOrcamento && a.t1.IdOrcamento == id)
    .GroupBy(gb => new { gb.t1.IdOrcamento })
    .Select(group => new LiberacaoItensDTO
    {
        TotalVenda = group.FirstOrDefault(item => item.t1.TotalLiquido),
        TotalLucro = group.FirstOrDefault(item => item.t2.Total 
            - (item.t2.Qtde*item.t2.Custo))
    }).ToList();

I think another way to solve the problem would be to use Distinct .

lista = contexto.Liberacoes
    .Join(contexto.ItensLibs,
        t1 => t1.IdOrcamento,
        t2 => t2.IdOrcamento,
        (t1, t2) => new { t1, t2 }
    )
    .Where(a => a.t1.IdOrcamento == a.t2.IdOrcamento && a.t1.IdOrcamento == id)
    .Distinct(comparer)
    .Select(item=> new LiberacaoItensDTO
    {
        TotalVenda = item.t1.TotalLiquido,
        TotalLucro = item.t2.Total - (item.t2.Qtde * item.t2.Custo))
    });

But then you have to implement a IEqualityComparer to compare by Budget ID.

    
21.10.2017 / 13:59
0

As explained in the comments, it would be enough to include in the group by and use the Key in the select, it would look something like this.

.GroupBy(gb => new { gb.t1.IdOrcamento, gb.t1.TotalLiquido })
.Select(item => new LiberacaoItensDTO
{
    TotalVenda = item.Key.TotalLiquido,
    TotalLucro = item.Sum(a => a.t2.Total - (a.t2.Qtde * a.t2.Custo))
}).ToList();

Here has a good usage reference.

    
23.10.2017 / 12:30