2010-11-22 18 views
8

Mam następujące Linq do grupowania listy według roku, a następnie miesiąca.Linq: grupa według roku i miesiąca i zarządzaj pustymi miesiącami

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

Moja prąd wyjściowy jest następujący:

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 
... 

Jak widać, miesiąc bez wartości, nie są zawarte w zapytaniu. Chciałbym je uwzględnić, mając następującą wydajność:

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 

Innymi słowy, muszę również uzyskać puste miesiące.

Czy mogę zaimplementować to za pomocą zapytania Linq? Dzięki z góry

+2

Dlaczego spędzamy tyle czasu wymyślanie trudnej, bez czytelnego i nieefektywnego Linq kiedy możemy zrobić to prostsze i bardziej czytelne w pętli? – Aliostad

+1

@Aliostad: Do tej pory rozwiązanie Linq Daniela jest dość proste i czytelne. Zawsze może skorzystać z pętli, jeśli odpowiedź na to pytanie okaże się zbyt skomplikowana przy użyciu Linq. – Heinzi

+0

Cóż, po prostu myślę, że jesteśmy w szalonym świecie Linq, który nie jest dobry. Tracisz całą tę moc debugowania. Chodzi o to, że podobnie jak XSLT, jeśli robi się zbyt skomplikowany, jest to dom z kartami. – Aliostad

Odpowiedz

18

Myślę, że chcesz coś takiego:

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

pamiętać, że:

  • trzeba wiedzieć co roku próbujemy wymyślić dane. Możesz pobrać to z innej kwerendy, oczywiście, aby znaleźć minimalne i maksymalne lata zaangażowane - lub może znaleźć minimum i założyć, że nie będzie nic w przyszłości (nie wiem, czy to ważne założenie, czy nie)
  • ten zostanie automatycznie prawidłowo uporządkowane
+0

Jon Skeen 1: Me 0. Ale nie lubię "Musisz wiedzieć, ile lat". Musisz wykonać jeszcze jedną kwerendę, aby wiedzieć, z jakimi latami współpracujesz. – Euphoric

+0

@Euhoric: Będę edytować, aby to wyjaśnić. –

+0

@John: W zapytaniu są błędy. To się nie kompiluje. Sprawdzam ... –

Powiązane problemy