【问题标题】:Using Linq to look for gap in dates使用 Linq 查找日期间隔
【发布时间】:2022-01-04 22:18:36
【问题描述】:

我有一个按 id 排序的可查询对象,然后按日期降序排列(最近的将首先出现),跟踪项目 (id) 何时在线。如果检测到间隔(超过 1 天),我想过滤掉间隔之前的所有日期,以便仅获取最近的在线天数范围。

目前我正在使用 for 循环进行循环,但是数据集非常大,所以我想使用 linq 来提高性能。

是否有任何方法可以按 id 比较记录,然后按日期比较记录,并在检测到间隙后删除该 id 的元素 (current.date - next.date != 1)?

Id Date
1 2022/01/01
1 2021/12/31
1 2021/12/25
2 2021/12/20
2 2021/12/19
2 2021/12/18
2 2021/12/15

会返回:

Id Date
1 2022/01/01
1 2021/12/31
2 2021/12/20
2 2021/12/19
2 2021/12/18

【问题讨论】:

  • 我不知道。但也许您可以更改查询数据的方式。如果您按日期范围查询,那么您知道该日期范围内有多少个唯一日期。因此,您可以按Id 对记录进行分组并计算唯一的Date。您可以过滤掉具有较少唯一 Date 数量的 Id,因为在您在查询中使用的日期范围内。
  • > "目前我正在使用 for 循环进行循环,但是数据集非常大,所以我想使用 linq 来提高性能。"这是错误的,LINQ 对性能没有帮助,如果有的话,它会由于所有迭代器的额外分配而降低性能。
  • 你想在服务器端这样做吗?
  • 日期请使用ISO 8601

标签: c# entity-framework linq


【解决方案1】:
var result = queryable
            .GroupBy(entry => entry.Id)
            .AsEnumerable()
            .Select(entryGroup => entryGroup
                .OrderByDescending(entry => entry.Date)
                .Aggregate((EntryGroup: new List<Entry>(), GapDetected: false), (accumulated, current) =>
                {
                    if (accumulated.GapDetected) return accumulated;
                    var previous = accumulated.EntryGroup.LastOrDefault();
                    if (previous == null || (previous.Date - current.Date).Days < 2) accumulated.EntryGroup.Add(current);
                    else accumulated.GapDetected = true;
                    return accumulated;
                }))
            .SelectMany(entryGroup => entryGroup.EntryGroup)
            .ToList();

请注意,实际上只有 GroupBy 部分代码作为 SQL 查询执行,其余查询在本地完成,因为它无法转换为 SQL。我想不出可以将整个查询转换为 SQL 的解决方案,但我想展示如何使用 LinQ 来完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 2017-10-27
    相关资源
    最近更新 更多