LINQ中的分组特定时间范围

时间:2011-07-26 08:41:19

标签: c# .net linq group-by

我有一个

List<Advertisement> 

Advertisement包含

public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }

我想要做的是使用GroupBy将List<Advertisement>中的元素按三个特定时间范围分组。三个时间范围如下:

  • x => x.StartDate > DateTime.Now.Subtract(TimeSpan.FromDays(1))
  • x => x.StartDate > DateTime.Now.Subtract(TimeSpan.FromDays(7))
  • x => x.StartDate > DateTime.Now.Subtract(TimeSpan.FromDays(365))

具有开始日期在最后一天的元素,具有上周开始日期的元素和具有去年开始日期的元素。

去年的元素组应该包括那些在上周和日期具有开始日期的元素。上周的元素组应包含最后一天的元素。

我似乎无法想到如何做到这一点。欢呼声。

3 个答案:

答案 0 :(得分:3)

由于您希望每个小组也包含以前的小组内容(例如,上周包括最后一天),我构建了一个联合查询

var today=items.Where(l=>l.StartDate>DateTime.Now.Subtract(TimeSpan.FromDays(1)));
var lastweek=items.Where(l=>l.StartDate>DateTime.Now.Subtract(TimeSpan.FromDays(7)));
var lastyear=items.Where(l=>l.StartDate>DateTime.Now.Subtract(TimeSpan.FromDays(365)));


var result = today.Select(d => new { Group="Last Day",item=d})
                  .Union(lastweek.Select(w => new {Group="Last Week",item=w}))
                  .Union(lastyear.Select(y => new {Group="Last Year",item=y}))
                  .GroupBy (l => l.Group,l=>l.item);

此查询的工作原理是创建3个子查询以选择相关数据。 然后,每个查询使用一个select运算符来选择匹配组名称和投影到匿名对象中的原始项目。 (基本上创建一个新对象,其中groupname为一个属性,而原始Item为另一个属性)。 然后我使用union将多个结果组合在一个大列表中。 (联盟有附加的属性,它剥离重复,但不应该有)。一旦我有了大名单,我可以按组名分组,第二个参数基本上将原始项目作为组值重新输入。

答案 1 :(得分:0)

您可以创建一个方法(或扩展名),它将返回一些特定于某个组的值,然后通过它进行分组。

答案 2 :(得分:0)

一种方法可能是编写一个扩展方法,该方法返回它所属的类别。

public static int GetCategory(this Advertisement advert)
{
    if(x.StartDate > DateTime.Now.Subtract(TimeSpan.FromDays(1)))
    {
        return 1;
    }
etc...
}

然后您可以按GetCategory属性进行分组。返回Enum而不是整数可能更好。