2011-02-06 160 views
0

如何使用Linq選擇最接近指定日期的記錄?這是針對具有日期,產品ID,位置ID和餘額的交易表。Linq選擇最接近日期的記錄

考慮到這些要求:

  • 如果有幾個在指定日期
  • 選擇最接近的現有交易,如果有沒有在指定日期
  • 選擇當天最後一筆交易顯示的多個地點的平衡(例如倉庫) - 每個倉庫將有單獨的交易
  • 顯示多個產品的餘額 - 每個產品將具有單獨的交易

表數據:

// code 
Id, TransDateTime, ProductId, WarehouseId, Balance 
1, 1-Jan-2011 00:00, 1,   1,   100 
2, 1-Jan-2011 00:00, 1,   2,   10 
3, 2-Jan-2011 00:00, 1,   1,   150 
4, 3-Jan-2011 00:00, 1,   2,   25 
5, 3-Jan-2011 00:00, 2,   1,   333 
6, 7-Jan-2011 00:00, 1,   1,   149 
7, 7-Jan-2011 01:00, 1,   2,   30 
8, 7-Jan-2011 02:00, 1,   2,   35 

考試日期和輸出

Date: 1-Jan would output: 
1, 1-Jan-2011 00:00, 1,   1,   100 
2, 1-Jan-2011 00:00, 1,   2,   10 

Date: 3-Jan would output: 
3, 2-Jan-2011 00:00, 1,   1,   150 
4, 3-Jan-2011 00:00, 1,   2,   25 
5, 3-Jan-2011 00:00, 2,   1,   333 
// product 1, warehouse 1 wasn't sold on the 3rd 
// so the row from 2-Jan is returned 

Date: 7-Jan would output: 
5, 3-Jan-2011 00:00, 2,   1,   333 
6, 7-Jan-2011 00:00, 1,   1,   149 
9, 7-Jan-2011 02:00, 1,   2,   35 
// product 2, warehouse 1 wasn't sold on the 7th 
// so the row from 3-Jan is returned 
// product 1, warehouse 2 was sold twice on the 7th 
// so the later one is used 

我認爲這將需要組進行分組(產品 - >倉庫 - >日期)或類似的。它超越了我的linq能力!

回答

5

步驟:
1)篩選出inputDate
2)按產品和倉庫
3)在每個組中記錄的組其餘之後發生的交易找到最近的事務
4)格式的結果對象

簡單的實現:

DateTime inputDate = ...; 
var result = transactions 
      .Where(t => t.TransDateTime.Date <= inputDate.Date) 
      .GroupBy(t => new {t.ProductId, t.WarehouseId}) 
      .Select(x => new { 
       x.Key, 
       LastTransaction = x.OrderByDescending(t => t.TransDateTime).First(), 
      }) 
      .Select(x => new { 
       Id = x.LastTransaction.Id, 
       Date = x.LastTransaction.TransDateTime, 
       ProductId = x.Key.ProductId, 
       WarehouseId = x.Key.WarehouseId, 
       Balance = x.LastTransaction.Balance, 
      }); 

如果你想要一些優化,你可以考慮實施MaxBy用於IEnumerable的擴展方法來代替x.OrderByDescending(t => t.TransDateTime).First()。如果您有很多交易,它會提高性能,因爲它是O(n)而不是O(n log n)MaxBy實現可以在這裏採用,例如:Simple LINQ question in C#

+0

+1似乎工作到目前爲止,謝謝,只是一個很容易修復的錯誤:'方法'第一'只能用作最終查詢操作。請考慮在這個實例中使用方法'FirstOrDefault'。' – 2011-02-07 00:35:12