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

Asked

Viewed 67 times

3

I got 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;
        }

That’s the result caught in the Postman

"TotalVenda": 5470,
"TotalLucro": 273.71

It turns out that this result is wrong. For this budget the Totalvenda is : 1094. It came to this result, because in Sum, he added by the amount of items, in this case this sale has 5 items. If I withdraw the Sum gives error in t1 and t2. The total profit in this case is 30% of the total sale, which does not give the above value. Can someone give me a hand on how to resolve the issue of SUM?

  • for you remove the sum would have to include in the group by , if Totalliquido is a list with the same velars you could also use the first.

  • @Marconciliosouza, and how would I do that? See that Totalvenda and Totallucro are part of Liberacaoitensdto and the other fields come from Models Release and Itenslib. And how would I do that? How do you include it in Groupby? I have grouped, for when I present Chart, the share of profit did not repeat itself according to the amount of items, as was happening.

  • to put in group by simply include in new { Gb.t1.Marking , Gb. " _ " . Totalliquid } .. and select you access with item.key.Totalliquid

  • is a little confused what you want to do, would mount the query in sql and put in question how it would be ?

  • The comment went wrong. The last way is working. If you want to answer, I mark the answer.

  • post your solution... not give to understand your structure.

  • 1

    @Marconciliosouza, as I said it’s okay.

  • I believe it was the way I replied, right ?

  • See if the answer is according to what you had commented.

Show 4 more comments

2 answers

0

Like me I mentioned the previous question all this would depend on logic and your data.

From what I understand Voce may have several elements in the group, but they all seem to have similar (or even equal) data, and hence Voce only wants one of them. You can use the 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 believe that another way to solve the problem would be using the 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 Voce has to implect a IEqualityComparer to compare by Budget id.

0

As explained in the comments, just include in group by and use Key in select, 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.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.