Linq - 按照日期时间对过去12个月进行分组 - 包括空月份

15 浏览
0 Comments

Linq - 按照日期时间对过去12个月进行分组 - 包括空月份

我有一个场景,需要根据日期时间字段的月份来获取对象的计数。

我找到了以下帖子,帮助我解决了部分问题...

Linq: group by year and month, and manage empty months

...但是我需要列出从今天日期开始的前12个月及每个月的对象计数,这是我遇到困难的地方。

我看过一些类似问题/解决方案的帖子,但选择了上面的帖子,因为还需要为计数为0的月份生成记录。

感谢任何对此能提供的帮助。

编辑

好的,多亏了Enigmativity(谢谢您花时间!),我进展了一点:

var news = from s in db.NewsItems
                   where s.SubmittedDate > first
                   select new 
                   {
                       Date = s.SubmittedDate,
                       Title = s.Title,
                   };
var grouping = from g in news.AsEnumerable()
                       select new NewsCountCollection
                       (
                           g.Date,
                           g.Title
                       );
var lookup = grouping.ToLookup(x => x.Month, x => x.Title);
var counts = from n in Enumerable.Range(-11, 12)
                    let Month = last.AddMonths(n)
                    select new
                    {
                        Month,
                        Count = lookup[Month].Count(),
                    };
var countList = from c in counts.AsEnumerable()
                        select new NewsCountMonthList
                        (
                            c.Month.ToString("MMMM"),
                            c.Count
                        );

...和以下内容

public class NewsCountCollection
{
    public DateTime Month { get; set; }
    public string Title { get; set; }
    public NewsCountCollection(DateTime date, string title)
    {
        this.Month = new DateTime(date.Year, date.Month, 1);
        this.Title = title;
    }
}
public class NewsCountMonthList
{
    public string Month { get; set; }
    public int Count { get; set; }
    public NewsCountMonthList(string month, int count)
    {
        this.Month = month;
        this.Count = count;
    }
}

...但是这种方法效率非常低...我不禁想到一定有更好的方法。我走在正确的轨道上吗?

0
0 Comments

原因:问题的出现是因为需要根据时间分组数据,并且包括过去12个月中的空月份。

解决方法:通过使用LINQ查询语句和一些日期计算,可以轻松地解决这个问题。以下是解决方法的具体步骤:

1. 首先,获取当前日期和时间,并将其存储在变量`now`中。

2. 创建一个新的`DateTime`对象`last`,其年份和月份与当前日期相同,但将日期设置为月份的第一天。这将表示最后一个月的第一天。

3. 使用`AddMonths`方法将`last`减去12个月,并将结果存储在`first`变量中。这将表示过去12个月的第一天。

4. 使用LINQ查询语句从`somethings`集合中筛选出日期字段在`first`和`last`之间的数据,并将结果存储在`query`变量中。这个查询语句还会创建一个新的匿名对象,其中包含一个`Month`属性,表示日期字段的年份和月份的第一天,以及一个`Something`属性,表示原始数据。

5. 使用`ToLookup`方法将`query`变量中的数据按照`Month`属性进行分组,并将结果存储在`lookup`变量中。这将创建一个`ILookup`类型的对象,其中键是月份的第一天,值是在该月份的第一天具有相同日期的所有`Something`对象。

6. 使用`Enumerable.Range`方法生成一个范围为-12到12的整数序列,并将每个整数与`last`进行月份计算。将每个计算得到的月份和对应的`lookup[Month]`中的数据数量存储在一个新的匿名对象中,并将结果存储在`counts`变量中。这将得到过去12个月中每个月的数据数量。

7. 最后,`counts`变量中的数据就是每个月的数据数量,可以根据需要进行进一步处理或使用。

以上就是解决问题的原因和方法的完整说明。通过使用LINQ查询语句和日期计算,可以方便地按照时间分组数据,并且还可以包括过去12个月中的空月份。

0