如何使用数据库中不存在的记录的默认值填充列表?



我想在数据库中获取过去一年的记录,按月对记录求和,然后用该信息填充折线图。 但是,当一个月没有记录时,我似乎无法弄清楚如何将其放入列表中的正确位置。 例如,如果 9 月或 10 月不存在任何内容,我的折线图就会跳过这几个月。 我尝试检查并添加之后的月份,但我无法按顺序获取它们。 有什么帮助吗?

Dim PointTotals = db.MemberRewards _
.Where(Function(r) sitewideFilterSelectedMemberIds.Contains(r.memberId) And r.supplier.name <> "AudStandard" And r.transactionDate >= startDate And r.transactionDate <= EndDate) _
.GroupBy(Function(r) New With {r.transactionDate.Value.Month, r.transactionDate.Value.Year}) _
.Select(Function(gr) New With {.month = gr.Key.Month, .year = gr.Key.Year, .totalPoints = gr.Sum(Function(r) r.points)}) _
.OrderBy(Function(gr) gr.year).ThenBy(Function(gr) gr.month)
Dim firstPeriodDate As Date
Dim currentDate As Date = DateAdd(DateInterval.Month, -1, startDate)
If PointTotals.Count > 0 Then
Dim firstPeriod = PointTotals.First
firstPeriodDate = CDate(firstPeriod.month & "/1/" & firstPeriod.year)
Else
firstPeriodDate = EndDate
End If
Dim months As New List(Of String)
Dim Points As New List(Of Integer)
Do While currentDate < firstPeriodDate
months.Add(currentDate.ToString("MMM"))
Points.Add(0)
currentDate = DateAdd(DateInterval.Month, 1, currentDate)
Loop
For Each period In PointTotals
months.Add(CDate(period.month & "/1/" & period.year).ToString("MMM"))
Points.Add(period.totalPoints)
Next
ViewBag.Months = """" & String.Join(""",""", months.ToArray) & """"
ViewBag.Points = String.Join(",", Points.ToArray)

我认为这是一个比尝试在循环后清理列表更优雅的解决方案。对代码的唯一更改是在 For Each Period 循环之前和中。

Dim PointTotals = db.MemberRewards _
.Where(Function(r) sitewideFilterSelectedMemberIds.Contains(r.memberId) And r.supplier.name <> "AudStandard" And r.transactionDate >= startDate And r.transactionDate <= EndDate) _
.GroupBy(Function(r) New With {r.transactionDate.Value.Month, r.transactionDate.Value.Year}) _
.Select(Function(gr) New With {.month = gr.Key.Month, .year = gr.Key.Year, .totalPoints = gr.Sum(Function(r) r.points)}) _
.OrderBy(Function(gr) gr.year).ThenBy(Function(gr) gr.month)
Dim firstPeriodDate As Date
Dim currentDate As Date = DateAdd(DateInterval.Month, -1, startDate)
If PointTotals.Count > 0 Then
Dim firstPeriod = PointTotals.First
firstPeriodDate = CDate(firstPeriod.month & "/1/" & firstPeriod.year)
Else
firstPeriodDate = EndDate
End If
Dim months As New List(Of String)
Dim Points As New List(Of Integer)
Do While currentDate < firstPeriodDate
months.Add(currentDate.ToString("MMM"))
Points.Add(0)
currentDate = DateAdd(DateInterval.Month, 1, currentDate)
Loop
Dim thisPeriodDate As Date
Dim previousPeriodDate As Date = currentDate
For Each period In PointTotals
thisPeriodDate = CDate(period.month & "/1/" & period.year)
Do While DateDiff(DateInterval.Month, previousPeriodDate, thisPeriodDate) > 1
months.Add(previousPeriodDate.ToString("MMM"))
Points.Add(0)
previousPeriodDate = DateAdd(DateInterval.Month, 1, previousPeriodDate)
Loop
months.Add(thisPeriodDate)
Points.Add(period.totalPoints)
previousPeriodDate = DateAdd(DateInterval.Month, 1, previousPeriodDate)
Next
ViewBag.Months = """" & String.Join(""",""", months.ToArray) & """"
ViewBag.Points = String.Join(",", Points.ToArray)

听起来在您的代码中添加您使用 .添加方法。 您需要使用几个月。Insert(position, CDate(....(( 和 Points.Insert(position, 0(,其中 position 是按正确顺序插入月份的正确索引。

我可以给你确切的命令,但你没有包括你在问题中引用的清理代码。

你可以采取很多方法来解决这个问题,我会提供一个数据库。

由于您要连接到数据库以拉取数据,因此您还可以在数据库端进行求和/分组。

您可以通过 3 个步骤执行此操作: 1(获取所有月份的不同列表,并将它们存储在临时表中 2( 按月创建求和,并将它们存储在另一个临时表中 3(在步骤2上留下加入步骤1(使用月份作为加入标准(,按照您关心的任何顺序排序,现在您拥有了所有月份。

有很多方法可以在SQL端实现这一点,上面的方法只是我认为很容易遵循的方法。

最新更新