[英]Linq select records closest to date
How do you use Linq to select the record that is closest to a specified date? 如何使用Linq选择最接近指定日期的记录? This is for a transaction table that has a date, product id, location id, and balance.
这是针对具有日期,产品ID,位置ID和余额的交易表。
Given these requirements: 鉴于这些要求:
Table data: 表格数据:
// 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
Test dates and outputs 测试日期和输出
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
I think it's going to require grouping of groups (product -> warehouse -> date) or similar. 我认为这将需要对分组进行分组(产品->仓库->日期)或类似的分组。 Its beyond my linq ability!
它超出了我的能力!
Steps: 脚步:
1) Filter out transactions that happened after inputDate
1)过滤掉
inputDate
之后发生的交易
2) Group rest of transactions by product and warehouse 2)按产品和仓库将其余交易分组
3) In each group find most recent transaction 3)在每个组中找到最近的交易
4) Format result object 4)格式化结果对象
Straightforward implementation: 简单实施:
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,
});
If you want some optimizations you can consider implementing MaxBy
extension method for IEnumerable
to replace x.OrderByDescending(t => t.TransDateTime).First()
. 如果要进行一些优化,可以考虑为
IEnumerable
实现MaxBy
扩展方法,以替换x.OrderByDescending(t => t.TransDateTime).First()
。 It will improve performance if you have many transactions since it is O(n)
instead of O(n log n)
. 如果您有很多事务,它将提高性能,因为它是
O(n)
而不是O(n log n)
。 MaxBy
implementation can be taken here for example: Simple LINQ question in C# MaxBy
实现可以在这里举例: C#中的简单LINQ问题
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.