Ras
Ras

Reputation: 628

C# LINQ create month and year list

I have a collection of flyers with a property FlyerDate as datetime and I want to create a dropdown list with month and year, such "nov 2015, dec 2015, jan 2016"...

This is my code:

var monthList = flyers.Where(i => i.FlyerDate != DateTime.MinValue && i.FlyerDate.Year >= 2013)
    .GroupBy(i => i.FlyerDate.Month)
    .Select(g => new { 
        Month = g.Key, 
        Year = g.First(i => i.FlyerDate != DateTime.MinValue).FlyerDate.Year, 
        FullDate = String.Concat(DateTimeFormatInfo.CurrentInfo.GetMonthName(g.Key), " ", g.First(i => i.FlyerDate != DateTime.MinValue).FlyerDate.Year), 
        Total = g.Count(i => i.FlyerID > 0) 
    }
);

I would that the GroupBy works both on month and year as in my case the list contains only the first occurrence of each months. Any hints?

Upvotes: 2

Views: 1742

Answers (3)

Fredrik
Fredrik

Reputation: 2317

var query = flyers.GroupBy(f => f.FlyerDate.ToString("MMM yyyy"))

foreach (var group in query)
{
    Console.WriteLine(group.Key);
    foreach (Flyer f in group)
        Console.WriteLine(f.FlyerDate);
}

Upvotes: 0

Ben Delaney
Ben Delaney

Reputation: 1082

I suspect your issue may be the GroupBy(i => i.FlyerDate.Month) clause. That grouping doesn't appear to respect year, so you'd be left with only 12 groups by the time you make it to your Select.

Incorporating the year into that GroupBy lambda could create a unique group for each month. Assuming your Month and Year are ints:

.GroupBy(i => (i.FlyerDate.Year * 12) + i.FlyerDate.Month)

might be a good place to start.

Upvotes: 0

Tim Schmelter
Tim Schmelter

Reputation: 460048

You need to group by an anonymous type containing both, the year and the month:

var monthList = flyers.Where(i => i.FlyerDate.Year >= 2013)
    .GroupBy(i => new { i.FlyerDate.Year, i.FlyerDate.Month })
    .Select(g => new { 
        Year  = g.Key.Year,
        Month = g.Key.Month, 
        FullDate = DateTimeFormatInfo.CurrentInfo.GetMonthName(g.Key.Month) + " " + g.Key.Year
    });

Btw, if you want the abbreviated month-name as your desired result suggests you need to use DateTimeFormatInfo.CurrentInfo.GetAbbreviatedMonthName instead of GetMonthName.

Upvotes: 5

Related Questions