Got it in single LINQ to SQL query:
var query = from o in north.Orders
from c in north.Customers.Where(c => c.CustomerID == o.CustomerID).DefaultIfEmpty()
from d in north.Order_Details.Where(d => d.OrderID == o.OrderID).DefaultIfEmpty()
group new { o, c, d } by new { o.OrderDate.Value.Year, c.CompanyName } into g
select new
{
Company = g.Key.CompanyName,
OrderYear = g.Key.Year,
Amount = g.Sum(e => e.d.UnitPrice * e.d.Quantity)
};
You can then simply get results:
var results = query.ToList();
Or sort it before fetching:
var results = query.OrderBy(g => g.Company).ThenByDescending(g => g.OrderYear).ToList();
I was curious about SQL that is generated by that LINQ to SQL query, so set custom Log
and here it is:
SELECT [t5].[value22] AS [Company], [t5].[value2] AS [OrderYear], [t5].[value] AS [Amount]
FROM (
SELECT SUM([t4].[value]) AS [value], [t4].[value2], [t4].[value22]
FROM (
SELECT [t3].[UnitPrice] * (CONVERT(Decimal(29,4),[t3].[Quantity])) AS [value], [t3].[value] AS [value2], [t3].[value2] AS [value22]
FROM (
SELECT DATEPART(Year, [t0].[OrderDate]) AS [value], [t1].[CompanyName] AS [value2], [t2].[UnitPrice], [t2].[Quantity]
FROM [dbo].[Orders] AS [t0]
LEFT OUTER JOIN [dbo].[Customers] AS [t1] ON [t1].[CustomerID] = [t0].[CustomerID]
LEFT OUTER JOIN [dbo].[Order Details] AS [t2] ON [t2].[OrderID] = [t0].[OrderID]
) AS [t3]
) AS [t4]
GROUP BY [t4].[value2], [t4].[value22]
) AS [t5]
ORDER BY [t5].[value22], [t5].[value2] DESC
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.6387
A bit scary, isn't it? But if you look closer, there is standard LEFT JOIN
used to combine all three tables together! All the rest is just grouping, sorting and summing.