使用没有间隙的外部列表对 linq 查询进行分组

Grouping a linq query with an external list with no gaps

我需要从数据库中获取折线图的数据,其中流从按这些时间跨度分组的当前日期 n days/weeks/months/years 返回。

数据库中的记录有一个与之关联的日期时间。

给定日期范围列表(一天的开始到一天的结束或一周的开始到一周的结束)如何使用 linq 获得连续流?

重要的是,在该日期范围内碰巧没有记录的情况下,流中没有间隙。它应该只是 return 一个零。

这是我尝试过的方法,但没有 return 任何值。

    Dim ranges = Enumerable.Range(0, itemCount).Select(Function(x) DateTime.Now.AddDays(-x).Date).ToList()

    Dim stream = Await DB.LogEntries.
        OfType(Of LogEntryContentView).
        GroupBy(Function(x) DbFunctions.TruncateTime(x.DateStamp)).
        Where(Function(x) ranges.Any(Function(y) y < x.Key AndAlso DbFunctions.AddDays(y, 1) > x.Key)).
        OrderBy(Function(x) x.Key).
        Select(Function(x) x.Count()).
        ToListAsync()

(C# 或 VB.NET 中的答案都可以,我都知道)

我会建议一种混合方法,您可以创建一个静态的 table 周期(它存储所有可能的范围),然后加入它们:

db.LogEntries.Join(db.Periods, a=> true, b => true, (a,b) = > new {LE=a, P=b})
.Where (p=> p.LE.DateStamp >= p.P.PeriodStartDate && p.LE.DateStamp <= p.P.PeriodEndDate)
.OrderBy(p=> p.P.PeriodStartDate)
.GroupBy(p=> new{Start=p.P.PeriodStartDate, End=p.P.PeriodEndDate})
.Select(p=> new{Start=p.Key.Start, End=p.P.End, Count=p.Count()})

最简单的方法是使用 .ToLookup(...)

您的查询看起来(类似于):

Dim ranges = Enumerable.Range(0, itemCount).Select(Function(x) DateTime.Now.AddDays(-x).Date).ToList()

Dim stream = DB.LogEntries.
    OfType(Of LogEntryContentView).
    GroupBy(Function(x) DbFunctions.TruncateTime(x.DateStamp)).
    Where(Function(x) ranges.Any(Function(y) y < x.Key AndAlso DbFunctions.AddDays(y, 1) > x.Key)).
    ToLookup(Function(x) x.Key)

Dim results = ranges.Select(Function (d) stream(d).Count()).ToList()

您需要让异步功能正常工作,但查找可以很好地确保您包括所有日期,包括那些没有数据的日期。