2013-03-11 28 views
0

我試圖使用Linq從受歡迎的NorthWind DB生成以下報告。它應該由Customer,OrderYear組成。使用Linq從Northwind DB生成報告

CustomerName OrderYear Amount 

我已經使用下表CustomerOrderOrder Details。 到目前爲止,這是我所做的。

NorthwindDataContext north = new NorthwindDataContext(); 

     var query = from o in north.Orders 
        group o by o.Customer.CompanyName into cg 
        select new 
        { 
         Company = cg.Key, 
         YearGroup = ( from y in cg 
               group y by y.OrderDate.Value.Year into yg 
               select new 
               { 
                Year = yg.Key, 
                YearOrdes = yg 
               }            
             ) 
        }; 


     foreach (var q in query) 
     { 
      Console.WriteLine("Customer Name : " + q.Company); 
      foreach (var o in q.YearGroup) 
      { 
       Console.WriteLine("Year " + o.Year); 
       Console.WriteLine("Sum " + o.YearOrdes.Sum(yo => yo.Order_Details.Sum(yd=> Convert.ToDecimal(yd.UnitPrice* yd.Quantity))));   
      } 

      Console.WriteLine(); 
     } 

它給了我預期的結果。我通過在後端運行t-sql進行了比較。但是,我有2個問題。

  1. 在Inner foreach中,第2條語句生成總和。這是否正確?或者有更好的嗎?
  2. 如何獲得Linq查詢本身的總和。

回答

0

得到它在單一的LINQ to SQL查詢:

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) 
      }; 

然後,您可以簡單地得到結果:

var results = query.ToList(); 

或者對其進行排序取前:

var results = query.OrderBy(g => g.Company).ThenByDescending(g => g.OrderYear).ToList(); 

我對LINQ to SQL查詢生成的SQL感到好奇,因此設置了自定義Log這裏它是:

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 

有點嚇人,不是嗎?但是如果你仔細觀察,有標準的LEFT JOIN用於將所有三個表結合在一起!其餘的只是分組,排序和總結。

+0

謝謝@Marcin – 2013-03-11 17:37:09