2010-11-22 4 views
8

У меня есть следующая Linq, чтобы группировать список по годам, затем по месяцам.Linq: группа по годам и месяцам, и управлять пустыми месяцами

var changesPerYearAndMonth = list 
       .GroupBy(revision => new { revision.LocalTimeStamp.Year, revision.LocalTimeStamp.Month }) 
       .Select(group => new { GroupCriteria = group.Key, Count = group.Count() }) 
       .OrderBy(x => x.GroupCriteria.Year) 
       .ThenBy(x => x.GroupCriteria.Month); 

Мой текущий выход заключается в следующем:

Year 2005, month 1, count 469 
Year 2005, month 5, count 487 
Year 2005, month 9, count 452 
Year 2006, month 1, count 412 
Year 2006, month 5, count 470 
... 

Как вы можете видеть, месяцы без значения, не включаются в запрос. Я хотел бы включить их, имея следующий вывод:

Year 2005, month 1, count 469 
Year 2005, month 2, count 0 
Year 2005, month 3, count 0 
... 
Year 2005, month 12, count 0 
Year 2006, month 1, count 412 
Year 2006, month 2, count 0 
... 
Year 2006, month 12, count 0 

Другими словами, мне нужно получить также пустые месяцев.

Могу ли я реализовать это с помощью запроса Linq? Заранее спасибо

+2

Почему мы тратим так много времени, придумывая неудобной, не читаемый и неэффективного Linq, когда мы можем сделать это проще и считываемый в цикле? – Aliostad

+1

@Aliostad: До сих пор решение Daniel Linq довольно прямолинейно и читаемо. Он всегда может вернуться к использованию цикла, если ответ на этот вопрос оказывается слишком сложным с использованием Linq. – Heinzi

+0

Ну, я просто думаю, что мы в мире Линк-сумасшедшего, который не очень хорош. Вы теряете всю эту способность отладки. Дело в том, что, подобно XSLT, если он становится слишком сложным, это карточный домик. – Aliostad

ответ

18

Я думаю, что вы хотите что-то вроде этого:

var changesPerYearAndMonth = 
    from year in Enumerable.Range(2005, 6) 
    from month in Enumerable.Range(1, 12) 
    let key = new { Year = year, Month = month } 
    join revision in list on key 
       equals new { revision.LocalTimeStamp.Year, 
          revision.LocalTimeStamp.Month } into g 
    select new { GroupCriteria = key, Count = g.Count() }; 

Заметьте, что:

  • Вы должны знать, что лет вы пытаетесь придумать для данных. Вы можете получить это из другого запроса, конечно, чтобы найти минимальные и максимальные годы - или, может быть, найти минимум и предположить, что в будущем ничего не будет (я не знаю, действительно ли это допустимое предположение или нет)
  • Это автоматически заказывается правильно
+0

Jon Skeen 1: Me 0. Но мне не нравится «Ты должен знать, какие годы». Вам нужно сделать еще один запрос, чтобы узнать, с какими годами вы работаете. – Euphoric

+0

@Euphoric: Я отредактирую, чтобы сделать это более ясным. –

+0

@John: В запросе есть некоторые ошибки. Он не компилируется. Я просматриваю ... –

Смежные вопросы