我想在过去的一年中在数据库中进行记录,按月对记录求和,然后用该信息填充折线图。但是,当一个月没有记录时,我似乎无法弄清楚如何将其放入列表中的正确位置。例如,如果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)
答案 0 :(得分:0)
听起来像在您的代码中添加使用.Add方法的缺少月份。您将需要使用months.Insert(position,CDate(....))和Points.Insert(position,0),其中position是正确的索引,可以按正确的顺序插入月份。
我可以给您确切的命令,但是您没有包含问题中引用的清理代码。
答案 1 :(得分:0)
您可以采用许多方法来解决此问题,我将提供一个数据库。
由于要连接到数据库以提取数据,所以您也可以在数据库端进行求和/分组。
您可以通过3个步骤进行操作: 1)获得所有月份的明确列表,并将它们存储在临时表中 2)按月创建汇总,并将其存储在另一个临时表中 3)在步骤2中离开加入步骤1(使用月份作为加入条件),按照您关心的顺序进行订购,现在您已经拥有了所有月份。
有很多方法可以在SQL端实现这一点,上面的方法只是我认为很容易遵循的一种方法。
答案 2 :(得分:0)
与循环后尝试清理列表相比,我认为这是一种更优雅的解决方案。对代码的唯一更改是在“每个周期”循环之前和之中。
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)