2013-10-29 35 views
2

我需要編寫一個查詢來獲取銷售的所有運輸成本,並將其與預計運輸成本進行比較。這裏是我的查詢:C#Linq GroupBy,獲取每個組中列的列表

var sales = (from sale in db.Sales 
      where sale.DateOfSale > startDate && sale.DateOfSale < endDate 
      group sale by new {sale.ItemID, sale.EstimatedShipping} into g 
      select new 
      { 
       ItemID = g.Key.ItemID 
       Estimate = g.Key.EstimatedShipping 
       ActualShipCosts = (from gSales in g select gSales.ActualShipping) 
      }).ToList(); 

看來,這樣做與不鍵獲取組或做g.Count()之類的話,使查詢運行非常緩慢,我不能讓這個查詢完成沒有超時。我能做些什麼來幫助表演?

+0

你對結果集做了什麼?也許有更好的方法來實現你的目標。 –

+0

分組之前查詢返回的記錄數量是多少?你需要列出ActualShipCosts嗎? – Krzysztof

+0

分組之前,我根據日期獲得50k左右的結果。我可以跳過小組並稍後過濾(需要約10秒),但我希望找出更快的選擇。我希望將ActualShipCosts作爲列表,但向ActualShipCosts查詢添加.ToList()似乎使其成爲無效查詢。 – IrkenInvader

回答

0

您可以嘗試執行ActualShipping選擇,而你正在構建的結果集:

var sales = db.Sales 
    .Where(sale => sale.DateOfSale > startDate && sale.DateOfSale < endDate) 
    .GroupBy(
     sale => new {sale.ItemID, sale.EstimatedShipping}, 
     sale => sale.ActualShipping) 
    .ToList(); 

不知道,但它可以防止額外的枚舉。

+0

我想我想在.GroupBy()和.ToList()之間選擇一個(g => new {g.Key,ShipCosts = g.ToList()}),但是我得到的錯誤與在此之前,Linq to Entities不承認這種方法.... – IrkenInvader

+0

原來,通過這些結果循環並列出.ActualShipping幾乎沒有時間......謝謝你,這正是我需要的! – IrkenInvader

0

很難說沒有所有的數據庫進行測試,但此行可能是這個問題:

(from gSales in g select gSales.ActualShipping) 

試試這個:

var sales = (from sale in db.Sales 
      where sale.DateOfSale > startDate && sale.DateOfSale < endDate 
      group sale by new {sale.ItemID, sale.EstimatedShipping} into g 
      select new 
      { 
       ItemID = g.Key.ItemID, 
       Estimate = g.Key.EstimatedShipping, 
       ActualShipCosts = g.Select(gSales => gSales.ActualShipping).ToList() 
      }).ToList(); 

這防止第二from。第一個查詢可能會做一些奇怪的連接,而使用簡單的Select不應該。

0

我覺得問題可能是由(from gSales in g select gSales.ActualShipping)造成的。 Linq group by在SQL中被翻譯爲group by,因此您無法直接訪問哪些表單組。 (from gSales in g select gSales.ActualShipping)的每個呼叫都會做單獨選擇。

第一種可能的解決方案:在ItemID,EstimatedShipping對上創建索引。

第二個可能的解決方案:

var sales = (from sale in db.Sales 
     where sale.DateOfSale > startDate && sale.DateOfSale < endDate 
     select new 
     { 
      ItemID = sale.ItemID 
      Estimate = sale.EstimatedShipping 
      ActualShipCosts = sale.ActualShipping 
     }).ToList(); 

var groupedSales = (from sale in sales 
     group sale by new {sale.ItemID, sale.EstimatedShipping} into g 
     select new 
     { 
      ItemID = g.Key.ItemID, 
      Estimate = g.Key.EstimatedShipping, 
      ActualShipCosts = g.Select(gSales => gSales.ActualShipping).ToList() 
     }).ToList(); 

這將做分組下線,記錄下載後。這肯定會減少查詢次數,但是您必須檢查您的數據庫以查看它是否更快。