How to concatenate sublists from a list and add values to them using Linq with C#

Asked

Viewed 277 times

1

Hello, I have the following 2 classes:

public class EstoqueItem {
    [Key]
    public int Id { get; set; }
    public decimal Qtd { get; set; }
    public Estoque Estoque { get; set;}
}

public class Estoque {
    [Key]
    public int Id { get; set; }
    public ICollection<EstoqueItem> Itens { get; set; }
}

At some point, I return a List<Estoque> and I need to group all the ICollection<EstoqueItem> by Id and add up its quantities. It would be something like SQL below:

SELECT Id, SUM(Qtd) as Qtd,
FROM EstoqueItem
WHERE /* as condições que retornam a lista aqui */
GROUP BY Id

How do I concatenate the sublists of the stock, grouping by id and adding their quantities at the end?

  • 1

    Its structure does not make much sense... Stock Room you have several items and each has its quantity?

  • I have several stocks and these stocks have several unique items. This is just a part of the structure itself (maybe that’s why it doesn’t make sense to you), it has this format because I’m creating a project for a logistics company

  • I tried to make the structure of my problem as simple as possible to arrive at a viable solution...

  • And this "cyclical" reference? An Item has a stock and a Stock has a collection of items

3 answers

1


You can use the Selectmany

Example:

estoques.SelectMany(x => x.Itens)
        .GroupBy( i=> i.Id)
        .Select(g => new { Id = g.Key, Total = g.Sum(x => x.Qtd) });
  • okay but what about the i.Count() ? i need to sum up the quantities that are in the items to know how many "x" id items I have for this selection

  • Got it, in this case you will need the groupby, I edited the answer with a possible solution.

1

You need to use the method SelectMany to do what you call "concatenate lists" and then group by item id and then sum the amounts.

Thus

var gp = estoques.SelectMany(x => x.Itens)
                 .GroupBy(x => x.Id)
                 .Select(x => new { Id = x.Key, Qtd = x.Sum(y => y.Qtd) });

See working on . NET Fiddle

  • SelectMany "achata" the result for a list of EstoqueItem

  • GroupBy will be applied in this list of EstoqueItem and will return a collection where each item will have a key, this being the value of the property defined as a grouper (Id, in the example) and will have a collection of items related to this key. From this collection of items (list of EstoqueItem, in this case) you can apply any valid operation with collections

  • Select causes each result item to be mapped to a new object where the property Id refers to the key of each item of the grouping and the property Qtd refers to the outcome of the operation Sum(x => x.Qtd) (add up the property Qtd for each item in the collection) above the value of the grouping
  • There’s something in the question that I think leads to an error. In the SQL example the query does the Group by Item Id and adds Qtd, but if Item Id is the key, it will not add, it will always bring Qtd by Id. I think it makes more sense to group by Stock ID and not by Stock ID.

0

You can use a Sum in the selection to sum the quantities in each stock

// estoques => representa a sua coleção de estoques ou a entidade do EF

foreach (var e in estoques.Select(x => new { Key = x.Id, Sum = x.Itens.Sum(y => y.Qtd) }))
{
    Console.WriteLine(string.Format("Estoque: {0}, Total: {1}", e.Key, e.Sum));
}

Example in Dotnetfiddle

Browser other questions tagged

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