C # LINQ создает список месяцев и лет

#c# #.net #linq

#c# #.net #linq

Вопрос:

У меня есть коллекция листовок со свойством FlyerDate datetime, и я хочу создать выпадающий список с указанием месяца и года, например «ноябрь 2015, декабрь 2015, январь 2016″…

Это мой код:

 var monthList = flyers.Where(i => i.FlyerDate != DateTime.MinValue amp;amp; 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) 
    }
);
 

Я бы хотел, чтобы это GroupBy работало как для месяца, так и для года, поскольку в моем случае список содержит только первое вхождение каждого месяца. Какие-либо подсказки?

Комментарии:

1. i.FlyerDate != DateTime.MinValue не требуется из-за второго условия

2. .GroupBy(i => i.FlyerDate.Month * 10000 i.FlyerDate.Year)

Ответ №1:

Вам нужно сгруппировать по анонимному типу, содержащему как год, так и месяц:

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

Кстати, если вы хотите использовать сокращенное название месяца в качестве желаемого результата, вам нужно использовать DateTimeFormatInfo.CurrentInfo.GetAbbreviatedMonthName вместо GetMonthName .

Ответ №2:

Я подозреваю, что ваша проблема может заключаться в этом GroupBy(i => i.FlyerDate.Month) пункте. Эта группировка, похоже, не учитывает год, так что к тому времени, когда вы доберетесь до своей, у вас останется всего 12 групп Select .

Включение года в эту GroupBy лямбду может создать уникальную группу для каждого месяца. Предполагая, что ваши Month и Year являются int s:

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

может быть, это хорошее место для начала.

Ответ №3:

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