Knowing Group by in Sql, having it in linq is a very power full feature. An interesting aspect of linq is that the OrderBy and GroupBy are using very different syntax when operating with multiple elements.
.GroupBy(c => new { c.ClientInitials, c.OwnerInitials, c.Department } )
.OrderBy(c => c.ClientInitials).ThenBy(c => c.OwnerInitials).ThenBy(c => c.Department)
If you are tricked into the assumption that you can do: .OrderBy(c => new { c.ClientInitials, c.OwnerInitials, c.Department } )
You will receive an Exception: “At least one object must implement IComparable."
Here is a an example on how one set of objects can be remodelled with linq to get reporting statistics.
The Resource class has a list of bookings and we start by flattening to one dimension of data for simplicity.
var resourceSet = from c in this.GetResources()
from o in c.Bookings
select
new
{
c.Department,
c.Initials,
c.Name,
o.ClientInitials,
o.OwnerInitials,
o.EventDate,
o.Description
};
This could also be achieved with a .SelectMany
var resourceSet = this.GetResources().SelectMany( c => c.Bookings, (c, o) => new { c.Department, c.Initials, c.Name, o.ClientInitials, o.OwnerInitials, o.EventDate, o.Description });
Then we group by the three main parameters and summarizes the statistics base on the booking periods.
IEnumerable<ReportViewModel> groupedByClientsOwnerDepartment = from c in resourceSet
group c by new { c.ClientInitials, c.OwnerInitials, c.Department }
into g
select new ViewModels.ReportViewModel()
{
ClientInitials = g.Key.ClientInitials,
OwnerInitials = g.Key.OwnerInitials,
Department = g.Key.Department,
CountBookingsLatestFullMonth = g.ToList().Where(f => f.EventDate.Month == DateTime.Today.AddMonths(-1).Month).Count(),
CountBookingsSinceLastFullMonth = g.ToList().Where(f => f.EventDate <= new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1)).Count() };
We then return to the view and order the output by the main 3 group by elements.
return View(groupedByClientsOwnerDepartment.OrderBy(c => c.ClientInitials).ThenBy(c => c.OwnerInitials).ThenBy(c => c.Department));
No comments: