Esta é a maneira mais eficiente:
Verifique a seguinte abordagem. Em vez de percorrer o grupo de clientes a cada vez em cada mês.
var query = myList
.GroupBy(c => c.CustId)
.Select(g => {
var results = new CustomerStatistics();
foreach (var customer in g)
{
switch (customer.OrderDate.Month)
{
case 1:
results.Jan += customer.Qty;
break;
case 2:
results.Feb += customer.Qty;
break;
case 3:
results.March += customer.Qty;
break;
default:
break;
}
}
return new
{
CustId = g.Key,
results.Jan,
results.Feb,
results.March
};
});
Ou este:
var query = myList
.GroupBy(c => c.CustId)
.Select(g => {
var results = g.Aggregate(new CustomerStatistics(), (result, customer) => result.Accumulate(customer), customerStatistics => customerStatistics.Compute());
return new
{
CustId = g.Key,
results.Jan,
results.Feb,
results.March
};
});
Solução completa:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp
{
internal class Program
{
private static void Main(string[] args)
{
IEnumerable<CustData> myList = GetCustData().Take(100);
var query = myList
.GroupBy(c => c.CustId)
.Select(g =>
{
CustomerStatistics results = g.Aggregate(new CustomerStatistics(), (result, customer) => result.Accumulate(customer), customerStatistics => customerStatistics.Compute());
return new
{
CustId = g.Key,
results.Jan,
results.Feb,
results.March
};
});
Console.ReadKey();
}
private static IEnumerable<CustData> GetCustData()
{
Random random = new Random();
int custId = 0;
while (true)
{
custId++;
yield return new CustData { CustId = custId, OrderDate = new DateTime(2018, random.Next(1, 4), 1), Qty = random.Next(1, 50) };
}
}
}
public class CustData
{
public int CustId { get; set; }
public DateTime OrderDate { get; set; }
public int Qty { get; set; }
}
public class CustomerStatistics
{
public int Jan { get; set; }
public int Feb { get; set; }
public int March { get; set; }
internal CustomerStatistics Accumulate(CustData customer)
{
switch (customer.OrderDate.Month)
{
case 1:
Jan += customer.Qty;
break;
case 2:
Feb += customer.Qty;
break;
case 3:
March += customer.Qty;
break;
default:
break;
}
return this;
}
public CustomerStatistics Compute()
{
return this;
}
}
}