2012-07-20 36 views
4

我有3個表,卡斯特,訂單和項目具有以下相關領域:LINQ多到SQL連接,GROUP BY和計數

Cust - CustID, CustName 
Order - OrderID, CustID 
Item - ItemID, OrderID 

我想找到訂單和項目每個總數顧客。

這是一個SQL語句,它生成我想要的東西,包含每個客戶的訂單總數和訂購的項目總數的客戶列表。

SELECT 
    Cust.CustID, Cust.CustName, 
    count(DISTINCT Order.OrderID) AS numOrders, 
    count(DISTINCT Item.ItemID) AS numItems 
FROM Cust 
LEFT JOIN Order ON Order.CustID = Cust.CustID 
LEFT JOIN Item ON Item.OrderID = Order.OrderID 
GROUP BY Cust.CustID, Cust.CustName 
ORDER BY numItems 

我在這個轉換爲LINQ的首次嘗試是僅計算項目以及與此想出了:

var qry = from Cust in tblCust 
    join Order in tblOrder on Cust.CustID equals Order.CustID 
    join Item in tblItem on Order.OrderID equals Item.OrderID 
    group Cust by new {CustID = Cust.CustID, CustName = Cust.CustName} into grp 
    orderby grp.Count() 
    select new 
    { 
     ID = grp.Key.CustID, 
     Name = grp.Key.CustName, 
     Cnt = grp.Count() 
    }; 

有了這個代碼,我得到異常:

Value cannot be null. Parameter name: inner 

上午我在正確的軌道上?我需要做什麼才能獲得這兩個數字?

回答

8
  1. 對於左連接 - 我建議使用一個fromwhereDefaultIfEmpty

  2. 您需要組使用匿名類型,以便將多個參數

值不能爲空。參數名稱:inner

是否有任何加入屬性可以爲空?

var qry = 
     from Cust in tblCust 
     from Order in tblOrder.Where(x => Cust.CustID == x.CustID) 
           .DefaultIfEmpty() 
     from Item in tblItem.Where(x => Order.OrderID == x.OrderID) 
          .DefaultIfEmpty() 
     group new { Cust, Order.OrderId, Item.ItemId } by new { Cust.CustID, Cust.CustName } into grp 
     let numItems = grp.Select(x => x.ItemId).Distinct().Count() 
     orderby numItems 
     select new 
     { 
      ID = grp.Key.CustID, 
      Name = grp.Key.CustName, 
      numOrders = grp.Select(x => x.OrderId).Distinct().Count(), 
      numItems, 
     }; 
+0

謝謝,這完美的作品。 – 2012-07-20 17:33:08

+0

雖然有一個問題,「orderby grp.Count()」如何與「numIems」相關? – 2012-07-20 17:41:20

+0

@JimRhodes - 我更新了答案以修復排序 – Aducci 2012-07-20 18:04:19