2010-11-22 39 views
8

Tôi có Linq sau để nhóm danh sách theo năm, sau đó theo tháng.LINQ: nhóm theo năm và tháng và quản lý các tháng trống

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

sản lượng hiện tại của tôi là như sau:

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

Như bạn thấy, tháng không có giá trị, không được bao gồm trong truy vấn. Tôi muốn bao gồm chúng, có kết quả sau:

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 

Nói cách khác, tôi cũng cần phải có các tháng còn trống.

Tôi có thể triển khai điều này bằng truy vấn LINQ không? Cảm ơn trước

+2

Tại sao chúng ta dành nhiều thời gian để đưa ra một LINQ khó khăn, không thể đọc và không hiệu quả khi chúng ta có thể làm đơn giản và dễ đọc hơn trong một vòng lặp? – Aliostad

+1

@Aliostad: Cho đến nay, giải pháp LINQ của Daniel khá đơn giản và dễ đọc. Anh ta luôn có thể quay trở lại sử dụng vòng lặp nếu câu trả lời cho câu hỏi này trở nên quá phức tạp khi sử dụng LINQ. – Heinzi

+0

Vâng, tôi chỉ nghĩ rằng chúng ta đang ở trong thế giới Linq-mad không tốt. Bạn mất tất cả sức mạnh gỡ lỗi đó. Vấn đề là, tương tự như XSLT, nếu nó trở nên quá phức tạp thì nó là một ngôi nhà của thẻ. – Aliostad

Trả lời

18

Tôi nghĩ rằng bạn muốn một cái gì đó như thế này:

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

Lưu ý rằng:

  • Bạn cần phải biết những gì bạn đang cố gắng năm để đưa ra dữ liệu. Dĩ nhiên, bạn có thể tìm nạp từ truy vấn khác để tìm số năm tối thiểu và tối đa có liên quan - hoặc có thể tìm mức tối thiểu và giả định sẽ không có gì trong tương lai (tôi không biết đây có phải là giả định hợp lệ hay không)
  • Điều này sẽ tự động được sắp xếp một cách chính xác
+0

Jon Skeen 1: Tôi 0. Nhưng tôi không thích "Bạn cần phải biết những gì năm" một phần. Bạn cần phải thực hiện thêm một truy vấn để biết bạn đang làm việc với những năm nào. – Euphoric

+0

@Euphoric: Tôi sẽ chỉnh sửa để làm rõ hơn. –

+0

@John: Có một số lỗi trong truy vấn. Nó không biên dịch. Tôi đang xem xét ... –

Các vấn đề liên quan