Search code examples
c#linq

LINQ Group By and merge properties and Summarize the Invoice Number


I have the follow List(InputData), and I would like to group by Vendor then by Type and Summarize by NumberInvoice and Concatenate by Month as you see the Input Data and this is the output

private static void Main()
    {
        var InputData= new List<Invoice>()
        {
        new Invoice{ Vendor = "Microsoft", NumberInvoice= 10, Type= "PC", Month = 1 },
        new Invoice{ Vendor = "Microsoft", NumberInvoice= 10, Type= "PC", Month = 2 },
        new Invoice{ Vendor = "Microsoft", NumberInvoice= 10, Type= "Surface", Month = 1 },
        new Invoice{ Vendor = "Microsoft", NumberInvoice= 20, Type= "PC", Month = 1 },
        new Invoice{ Vendor = "Microsoft", NumberInvoice= 20, Type= "PC", Month = 2 },
        new Invoice{ Vendor = "Microsoft", NumberInvoice= 30, Type= "Surface", Month = 1 },
        new Invoice{ Vendor = "IBM", NumberInvoice= 50, Type= "Network", Month = 5 },
        new Invoice{ Vendor = "IBM", NumberInvoice= 60, Type= "Graphic Card", Month = 6 }
        };
    }
    
    public class Invoice
    {
        public string Vendor { get; set; }
        public int NumberInvoice{ get; set; }
        public string Type{ get; set; }
        public int Month { get; set; }
    }

I did this so far, but it is not working as my output result. If I comment the follow line, it will show my result but without Summarizing.

//NumberInvoice = Enumerable.Sum((decimal)key.NumberInvoice)

The Code:

var result = InputData
                    .GroupBy(
                        x => new {
                            x.Vendor,
                            x.Type,
                            x.NumberInvoice
                        }, // key selector
                        x => x.Month, // element selector
                        (key, month) => new Invoice
                        {
                            Vendor = key.Vendor,
                            Type = key.Type,
                            month = string.Join(",", month),
                            NumberInvoice = Enumerable.Sum((decimal)key.NumberInvoice)
                        })
                    .ToList();

Update (Explain): I need to Group by Columns, and concatenate 1 column, and do the Sum for 1 Column.

  1. Group by : 1st by Vendor then by Type
  2. Concatenate by: Month
  3. Sum by :NumberInvoice

So the result in above example is: This the output


Solution

  • This will work

                var result = InputData
                    .OrderBy(x => x.Month)
                    .GroupBy(x => x.Month)
                    .SelectMany(x => x.GroupBy(y => new {y.Vendor, y.Type, y.NumberInvoice})
                    .Select(y => new { Vendor = y.Key.Vendor, Type = y.Key.Type, month = x.Key, numberInvoices = y.Count()}).ToList()).ToList();