2009-04-18 6 views
31

Ho una tabella con un campo datetime. Voglio recuperare un set di risultati raggruppato per la combinazione mese/anno e il numero di record visualizzati in quel mese/anno. Come può essere fatto in LINQ?LINQ: Raggruppa per mese e anno all'interno di un campo datetime

Il più vicino che sono stato in grado di capire è in 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) 

ma non vorrei dire che funziona ...

risposta

59
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() }; 

Ecco l'elenco delle funzioni disponibili in DateTime LINQ. Per questo lavoro avrete anche bisogno di capire multi-column grouping

hanno ordinato decrescente

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); 
+0

voglio ordinare questo per mesi come il primo mese corrente in alto e il mese precedente successivo e così via ?? per favore aiuto –

+0

puoi farlo aggiungendo un orderbydescending – Jeremy

2

This Site ha un esempio che dovrebbe riempire il vostro bisogno.

Questa è la sintassi di base:

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

Con un elenco contenente gli ordini di più anni, questo raggrupperà gli ordini da gennaio 2010, 2011 e 2012 nello stesso gruppo. – Moulde

1

si potrebbe anche fare in questo modo

from o in yg 
group o by o.OrderDate.ToString("MMM yyyy") into mg 
select new { Month = mg.Key, Orders = mg } 

Il risultato sarà

{Gennaio 2014 , 25} {febbraio 2015, 15} ecc ...

7

Questo è per coloro che stanno cercando di realizzare lo stesso, ma usando espressioni lambda.

Supponendo che si disponga già di una raccolta di entità e che ogni entità abbia OrderDate come una delle sue proprietà.

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(); 

Se non è necessario la raccolta di SelectListItem poi basta sostituire il select con questo:

.Select(x => string.Format("{0}/{1} (Count: {2})", x.Key.Year, x.Key.Month, x.Count())) 
0

Ecco una soluzione semplice per raggruppare in 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();