根据时间框架和按月分组获得结果
本文关键字:结果 时间 框架 | 更新日期: 2023-09-27 18:08:28
我有一个包含许多表的数据库。其中一个表VersionBuild包含一个日期列。我得到的结果使用以下查询,只选择记录出现在一定的时间范围内(如。最近6个月)
我使用的代码如下
DateTime startDate = DateTime.Now.AddMonths(-(timeFrame));
var grouped = db.VersionBuilds
.Where(r => r.product_id == id && r.date > startDate)
.GroupBy(r => new { r.date.Year, r.date.Month })
.Select(r => new {
month = getMonthName(r.Key.Month),
totalIssues = r.Sum(zz => zz.AcrolinxReport.total_issues)
});
return grouped;
代码的一个问题是,如果没有特定月份的记录,它会忽略它。我在图表中显示返回的信息,因此这在数据中留下了空白。例如,如果我在5月和6月有记录,它将返回5月和6月的数据,但我想要的是返回指定时间范围内所有月份的数据,无论是否有任何数据。
我相信这对你有用。没有数据很难测试,但我认为你应该没有任何问题。
// Assume 'timeframe' is a positive integer.
// Get the start date.
DateTime startDate = DateTime.Now.AddMonths(-timeframe);
// Generate a list of months (year and month, actually) beginning
// with the month of 'startDate'.
var months =
Enumerable
.Range(0, timeframe)
.Select(x => startDate.AddMonths(x))
.Select(x => new { x.Year, x.Month });
// Create builds query.
var builds =
db.VersionBuilds
.Where(r => r.product_id == id && r.date > startDate)
.GroupBy(r => new { r.date.Year, r.date.Month })
.Select(r => new {
Month = r.Key.Month,
Year = r.Key.Year,
TotalIssues = r.Sum(zz => zz.AcrolinxReport.total_issues));
// Join 'months' on 'builds'
var grouped =
months
.GroupJoin(
builds.AsEnumerable(),
date => date,
build => new { build.Year, build.Month },
(date, buildGroup) => new {
date.Year,
date.Month,
TotalIssues = buildGroup.Sum(x => x.TotalIssues) })
.OrderBy(x => x.Year)
.ThenBy(x => x.Month)
.Select(x => new { Month = getMonth(x.Month), x.TotalIssues });
你可以尝试这样做:
首先,我们创建一个包含给定时间范围内所有月份的列表例如,如果我们现在运行这个并将timeFrame设置为3,那么该列表将包含以下日期时间
- 2015-08-15…
- 2015-07-15…
- 2015-06-15
代码如下:
var monthsInTimeFrame = new List<DateTime>();
for(int i = timeFrame; i>=0 ; i--)
{
monthsInTimeFrame.Add(DateTime.Now.AddMonths(-i));
}
然后你继续用你已经得到的方式获取你的数据,但有一个小的变化。而不是创建一个对象列表匿名类型,创建命名类型的对象列表。我取了一个模糊的名字:Data
。你想取什么名字都行。此外,这种类型将具有两个额外的属性,一个是Year
,另一个是Month
。我们需要它们,以便确定预期月份中的特定月份是否在列表中。
DateTime startDate = DateTime.Now.AddMonths(-(timeFrame));
var grouped = db.VersionBuilds
.Where(r => r.product_id == id && r.date > startDate)
.GroupBy(r => new { r.date.Year, r.date.Month })
.Select(r => new Data
{
Year = r.Key.Name,
Month = r.Key.Month,
MonthName = getMonthName(r.Key.Month),
TotalIssues = r.Sum(zz => zz.AcrolinxReport.total_issues)
}).ToList();
注意,我们必须在查询结束时调用ToList
,因为下面我们将使用Add
方法来添加缺失的月份。
最后,我们必须遍历monthsInTimeFrame
的项:
foreach(var month in monthsInTimeFrame)
{
// If there isn't any item in the list called
// grouped with the same year and month of the current month,
// we have to add a new item in this list
if(!grouped.Any(item=>item.Year==month.Year &&
item.Month==month.Month))
grouped.Add(new Data
{
Year = month.Year,
Month = month.Month,
MonthName = getMonthName(month.Month),
TotalIssues = 0
});
}
return grouped;
Data
类的定义可以是这样的:
public class Data
{
public int Year { get; set; }
public int Month { get; set; }
public string MonthName { get; set; }
public int TotalIssues { get; set; }
}