I am trying to get the name of the company to show on top of each group that contains OrderDate and the Total made, for example:
Ray's Company
11/1/1996 12:00:00 AM
2296.00
Jay's Company
3/10/1997 12:00:00 AM
956.68
Bee's Company
11/13/1997 12:00:00 AM
1416.00
I have only been able to show the OrderDate and Total, but not the company's name. Would like to know how I could show the company's name as well. Here is what I have thus far:
static void Exercise21()
{
List<Customer> customers = DataLoader.LoadCustomers();
var companys = (from y in customers
group y by y.CompanyName into newCompany
select newCompany).ToList(); //this is company name
var customersSort = (from customer in customers
from x in customer.Orders
group x by x.OrderDate into newGroup
select newGroup).ToList();
string line = "{0,-35}";
Console.WriteLine(line, "Category");
Console.WriteLine("======================================================================================");
foreach (var customerGroup in customersSort)
{
Console.WriteLine();
Console.WriteLine(customerGroup.Key);
foreach (var customer in customerGroup)
{
Console.WriteLine(line, customer.Total);
}
}
}
To address your question and consideration, the company name needs to output in the iteration. You can handle this by ensuring you are handling your grouping in the context of iterating through the List<Customer>
sequence. This can be done in the foreach-loop or in the expression (referenced to as the alternative in this answer.
So, there are a couple implementations you can do here but reflect the same notion: grouping in the context of iterating.
In the following one I'm going to represent handling the lambda linq expressions in the context of iterating with the foreach-loop on List<Customer> Customers
.
public class Customer
{
public string CompanyName { get; set; }
public IEnumerable<Order> Orders { get; set; }
}
public class Order
{
public DateTime OrderDate { get; set; }
public double Total { get; set; }
}
static IEnumerable<Customer> GetCustomersMocks()
{
return new List<Customer>
{
new Customer
{
CompanyName = "Ray's Company",
Orders = new List<Order>
{
new Order { OrderDate = DateTime.Parse("11/1/1996 12:00:00 AM"), Total = 1148},
new Order { OrderDate = DateTime.Parse("11/1/1996 12:00:00 AM"), Total = 1148}
}
},
new Customer
{
CompanyName = "Jay's Company",
Orders = new List<Order>
{
new Order { OrderDate = DateTime.Parse("3/10/1997 12:00:00 AM"), Total = 478.34 },
new Order { OrderDate = DateTime.Parse("3/10/1997 12:00:00 AM"), Total = 478.34 }
}
},
new Customer
{
CompanyName = "Bee's Company",
Orders = new List<Order>
{
new Order { OrderDate = DateTime.Parse("11/13/1997 12:00:00 AM"), Total = 708 },
new Order { OrderDate = DateTime.Parse("11/13/1997 12:00:00 AM"), Total = 708 }
}
}
};
}
static void Exercise21()
{
//List<Customer> customers = DataLoader.LoadCustomers();
var customers = GetCustomersMocks();
string line = "{0,-35}";
Console.WriteLine(line, "Category");
Console.WriteLine("======================================================================================");
foreach (var customer in customers)
{
Console.WriteLine();
Console.WriteLine(customer.CompanyName);
var groupedOrdersList = (from c in customer.Orders group c by c.OrderDate);
foreach (var groupedOrders in groupedOrdersList)
{
Console.WriteLine(groupedOrders.Key);
Console.WriteLine(line, (from g in groupedOrders select g.Total).Sum());
}
}
}
Here is an alternative that uses .SelectMany
and GroupBy
.
var groupedCustomerByCompanyNameOrderDate = customers.SelectMany(c => c.Orders.Select(o => new { c.CompanyName, o.OrderDate, o.Total }))
.GroupBy(c => new { c.CompanyName, c.OrderDate });
foreach (var g in groupedCustomerByCompanyNameOrderDate)
{
Console.WriteLine();
Console.WriteLine(g.Key.CompanyName);
Console.WriteLine(g.Key.OrderDate);
Console.WriteLine(g.Sum(o => o.Total));
}
In the code above, your selecting (projecting to) an anonymous type and flattening the IEnumerable<IEnumerable<T>>
Result to IEnumerable<T>
(though it is deferred execution). You then perform a GroupBy
on that sequence and iterate with one foreach loop (without nesting another foreach loop).
see Enumerable.SelectMany
documentation
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.