使用没有间隙的外部列表对 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()
您需要让异步功能正常工作,但查找可以很好地确保您包括所有日期,包括那些没有数据的日期。
我需要从数据库中获取折线图的数据,其中流从按这些时间跨度分组的当前日期 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()
您需要让异步功能正常工作,但查找可以很好地确保您包括所有日期,包括那些没有数据的日期。