LINQ:在日期时间字段中按月份和年份分组

51

我有一个包含datetime字段的表。我想获取按月/年组合分组的结果集,并显示每个月/年中出现的记录数。如何在LINQ中实现?

我最接近的解决方案是在TSQL中:

select substring(mo,charindex(mo,'/'),50) from (
select mo=convert(varchar(2),month(created)) + '/' + convert(varchar(4), year(created)) 
 ,qty=count(convert(varchar(2),month(created)) + '/' + convert(varchar(4), year(created)))
from posts 
group by convert(varchar(2),month(created)) + '/' + convert(varchar(4), year(created))
) a
order by substring(mo,charindex(mo,'/')+1,50)

但我不会说那会起作用...

5个回答

87
var grouped = from p in posts
     group p by new { month = p.Create.Month,year= p.Create.Year } into d
     select new { dt = string.Format("{0}/{1}",d.Key.month,d.Key.year), count = d.Count() };
这里是 LINQ中可用的 DateTime 函数列表。为了让这个工作,您还需要理解多列分组
按降序排列。
var grouped = (from p in posts 
  group p by new { month = p.Create.Month,year= p.Create.Year } into d 
  select new { dt = string.Format("{0}/{1}",d.Key.month,d.Key.year), count = d.Count()}).OrderByDescending (g => g.dt);

我想按月份排序,就像当前月份在顶部,上个月在下面,以此类推。请帮忙。 - Praveen Prasad
你可以通过添加一个 orderbydescending 来实现。 - Jeremy

30

这是给那些想要使用 Lambda 表达式实现相同目标的人。

假设您已经拥有一组实体,并且每个实体都有 OrderDate 作为其属性之一。

yourCollection
// This will return the list with the most recent date first.
.OrderByDescending(x => x.OrderDate)
.GroupBy(x => new {x.OrderDate.Year, x.OrderDate.Month})
// Bonus: You can use this on a drop down
.Select(x => new SelectListItem
        {
           Value = string.Format("{0}|{1}", x.Key.Year, x.Key.Month),
           Text = string.Format("{0}/{1} (Count: {2})", x.Key.Year, x.Key.Month, x.Count())
        })
.ToList();
如果您不需要SelectListItem集合,则只需使用以下代码替换

7
你也可以这样做。
from o in yg
group o by o.OrderDate.ToString("MMM yyyy") into mg
select new { Month = mg.Key, Orders = mg }

您的结果将会是:

{2014年1月,25} {2015年2月,15} 等等...


适用于对象,但不适用于将被发送到数据库的 IQueryable<>。 在那里,您会收到“方法'System.String ToString(System.String)'没有支持的SQL翻译”。 - Thymine

1

这个网站有一个例子,应该可以满足您的需求。

这是基本语法:

from o in yg
group o by o.OrderDate.Month into mg
select new { Month = mg.Key, Orders = mg }

14
有一个包含多年订单的列表,这将把2010年、2011年和2012年一月份的订单分为同一组。 - Moulde

0

这里有一个简单的DateTime分组解决方案。

List<leaveallview> lav = new List<leaveallview>();
lav = dbEntity.leaveallviews.Where(m =>m.created==alldate).ToList();
dynamic lav1 = lav.GroupBy(m=>m.created.Value.GetDateTimeFormats()).FirstOrDefault().ToList();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接