I have a Customer
class:
public class Customer
{
public Guid Id { get; set; }
// Some other properties...}
And three transactions classes that have a reference to Customer
:
public class Order
{
public Guid CustomerId { get; set; }
// Some other properties...}
public class Invoice
{
public Guid CustomerId { get; set; }
// Some other properties...}
public class Payment
{
public Guid CustomerId { get; set; }
// Some other properties...}
I have a collection for each of transaction type. And I want to get this collection to be "grouped" by their elements CustomerId
properties. So, as a result I'd like to get a collection of such objects:
public class CustomerInfo
{
public CustomerInfo(Guid customerId, IEnumerable<Order> orders,
IEnumerable<Invoice> invoices, IEnumerable<Payment> payments){...}
public Guid CustomerId { get; set; }
public IEnumerable<Invoice> Invoices { get; set; }
public IEnumerable<Order> Orders { get; set; }
public IEnumerable<Payment> Payments { get; set; }
}
Right now I am doing so by this function:
private IEnumerable<CustomerInfo> _GetCustomerInfo(
IEnumerable<Payment> payments, IEnumerable<Invoice> invoices,
IEnumerable<Order> orders)
{
var invoicesGroupdByCustomers = invoices.GroupBy(x => x.CustomerId);
var ordersGroupdByCustomers = orders.GroupBy(x => x.CustomerId);
var paymentsGroupdByCustomers = payments.GroupBy(x => x.CustomerId);
var result = new List<CustomerInfo>();
foreach (var group in invoicesGroupdByCustomers)
result.Add(new CustomerInfo(group.Key,
ordersGroupdByCustomers.FirstOrDefault(x => x.Key == group.Key),
group,
paymentsGroupdByCustomers.FirstOrDefault(x => x.Key == group.Key)));
foreach (var group in ordersGroupdByCustomers)
if (!result.Any(x => x.CustomerId == group.Key))
result.Add(new CustomerInfo(group.Key,
group,
invoicesGroupdByCustomers.FirstOrDefault(x => x.Key == group.Key),
paymentsGroupdByCustomers.FirstOrDefault(x => x.Key == group.Key)));
foreach (var group in paymentsGroupdByCustomers)
if (!result.Any(x => x.CustomerId == group.Key))
result.Add(new CustomerInfo(group.Key,
ordersGroupdByCustomers.FirstOrDefault(x => x.Key == group.Key),
invoicesGroupdByCustomers.FirstOrDefault(x => x.Key == group.Key),
group));
return result;
}
Here is sample of calculations where I use these transactions collections:
private Dictionary<Guid, decimal> _CalculateSales(
IEnumerable<CustomerInfo> customersSalesInfo)
{
var result = new Dictionary<Guid, decimal>();
foreach (var customerInfo in customersSalesInfo)
{
var sales = customerInfo.Invoices.Sum(x => x.Header.SubTotalAmt) +
customerInfo.Orders.Sum(x => x.Header.SubTotalAmt) -
customerInfo.Payments.Sum(x => x.Header.SubTotalAmt);
result.Add(customerInfo.CustomerId, sales);
}
return result;
}
Is there a better approach?