繁体   English   中英

C# - LINQ - 按日期范围分组

[英]C# - LINQ - Group collection by date range

假设我有以下项目集合:

ID: 1, Date: 10/01/2020 08:00
ID: 2, Date: 10/01/2020 12:00
ID: 3, Date: 10/01/2020 18:00
ID: 4, Date: 11/01/2020 06:00
ID: 5, Date: 11/01/2020 08:00

ID: 6, Date: 11/01/2020 08:01
ID: 7, Date: 11/01/2020 12:00
ID: 8, Date: 12/01/2020 01:00
ID: 9, Date: 12/01/2020 07:00

ID: 10, Date: 12/01/2020 12:00
ID: 11, Date: 12/01/2020 14:00
ID: 12, Date: 12/01/2020 16:00

基于上述集合,我想创建 3 个组,其中包含按时间间隔分组的记录 - 从一个小时 08:00 到第二天 07:59:

XX.01.2020 08:00 - XX(+1).01.2020 07:59

output 分组集合应如下所示

**Group 1 (10.01.2020 08:00 - 11.01.2020 07:59):**
   ID: 1, Date: 10/01/2020 08:00
   ID: 2, Date: 10/01/2020 12:00
   ID: 3, Date: 10/01/2020 18:00
   ID: 4, Date: 11/01/2020 06:00
   ID: 5, Date: 11/01/2020 07:59
**Group 2 (11.01.2020 08:00 - 12.01.2020 07:59):**
   ID: 6, Date: 11/01/2020 08:00
   ID: 7, Date: 11/01/2020 12:00
   ID: 8, Date: 12/01/2020 01:00
   ID: 9, Date: 12/01/2020 07:00
**Group 3 (12.01.2020 08:00 - 13.01.2020 07:59):**
   ID: 10, Date: 12/01/2020 12:00
   ID: 11, Date: 12/01/2020 14:00
   ID: 12, Date: 12/01/2020 16:00

这可以使用 Linq 吗? 先感谢您

我不知道你有什么收藏,但假设你有Dictionary<int, DateTime>

然后你可以像这样分组,如果在 8 点之后,则“四舍五入”到当天,如果在 8 点之前,则“四舍五入”到前一天:

    var groups = dictionary.GroupBy(x =>
        {
            var dt = x.Value;
            if (dt.Hour >= 8)
                return dt.Date;
            else
                return dt.Subtract(TimeSpan.FromHours(24)).Date;
        });

您没有指定是否希望它在数据库中运行。

但我认为 go 的一种非常简单的方法可能是减去 8 小时以使其成为一整天,您可以将其用作分组的基础:

var result = list.GroupBy(x => x.Date.AddHours(-8).Date);

如果你想得到一个正确的“从”和“到”日期分组,就像你似乎指定的那样,你可以把这个投影拍到最后:

    .Select(g => new {
        From = g.Key.AddHours(8),
        To = g.Key.AddHours(8).AddDays(1),
        Values = g.AsEnumerable()
    });

这可能适用于内存 collections 上的普通 Linq。 不会被翻译成 SQL 虽然如果你在IQueryable上运行它(除非我很迟钝)。

如果您接受另一个答案,那没关系,如果这对您来说看起来更好。 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM