2012-06-08 29 views
2

這將是一個兩部分問題。LINQ - 按多個屬性對列表進行分組,並返回一個包含數組成員的對象

我試圖建立一個數據結構,用於谷歌圖表API(特別是他們的數據表)。

這裏是我的代碼,目前的情況是:

return Json.Encode(
    RMAs 
    .Where(r => r.CreatedDate.Year > DateTime.Now.Year - 4) //Only grab the last 4 years worth of RMAs 
    .GroupBy(r => new { Problem = r.Problem, Year = r.CreatedDate.Year, Quarter = ((r.CreatedDate.Month)/3) }) 
    .Select(r => new { Problem = r.Key.Problem, Year = r.Key.Year, Quarter = r.Key.Quarter, Count = r.Count() }) 
); 

這讓我非常接近。這讓我類似於如下內容的數組:

{"Problem":"It broke!","Year":2012,"Quarter":2,"Count":3}, 
{"Problem":"It broke!","Year":2012,"Quarter":1,"Count":1} 

但是,我要的是對數據進行進一步的「問題」屬性,使該季度對每一個問題的數組(這使得分組數據結構更容易迭代)。所需結構的一個例子:

{"Problem":"It broke!", 
    {"Year":2012,"Quarter":2,"Count":3}, 
    {"Year":2012,"Quarter":1,"Count":1} 
}, 
{"Problem":"Some other problem", 
    {"Year":2012,"Quarter":1,"Count":31} 
} 

問題的第二部分:怎樣才能保證我的數據每個季度(再次,這使得它容易迭代建立數據表使用API​​),即使在該季度沒有發生「問題」?使用相同的例子末班時間:

{"Problem":"It broke!", 
    {"Year":2012,"Quarter":2,"Count":3}, 
    {"Year":2012,"Quarter":1,"Count":1} 
}, 
{"Problem":"Some other problem", 
    {"Year":2012,"Quarter":2,"Count":0} 
    {"Year":2012,"Quarter":1,"Count":31} 
} 
+0

在你問題的第二部分,是你過濾出沒有問題的年/季組合(即年= 2012,季= 3)? –

回答

1
  1. 以下內容添加到您的查詢:

    .GroupBy(x => x.Problem) 
    .ToDictionary(g => g.Key, g => g.Select(x=>new { Year=x.Year, Quarter=x.Quarter, Count = x.Count })); 
    
  2. 您必須插入.ToDictionary之前)以上以下(:

    .Select(g => 
        new { 
        Key = g.Key, 
        Items = 
         g 
         .GroupBy(r => r.Year) 
         .SelectMany(gy => 
          gy.Concat(
          Enumerable.Range(1,5) 
           .Where(q => !gy.Any(r=>r.Quarter == q)) 
           .Select(q => new { Problem = g.Key, Year = gy.Key, Quarter = q, Count = 0 }) 
         ) 
         ) 
        } 
    ) 
    

我想...試試看: )

然而,我建議不要採用這種方法,並在客戶端上創建「空」記錄,以避免帶寬過度使用。

2

感謝Mr. TA的靈感,並告訴我你可以使用LINQ對分組。

我已經在本地環境中測試了這一點,並且LINQ確實返回了與總計數相關的年/季度組的數組綁定的問題列表。我不知道Json.Encode是否以正確的格式編碼。

下面的LINQ應返回適合你所需要的格式匿名類型:

編輯:查詢現在返回其中至少一個問題的發生,但並沒有出現

指定問題季度數= 0
var quarters = RMAs 
    .Where(rma => rma.CreatedDate.Year > DateTime.Now.Year - 4) 
    .GroupBy(rma => new { 
     Year = rma.CreatedDate.Year, 
     Quarter = ((rma.CreatedDate.Month)/3) 
    }); 

return Json.Encode(
    RMAs 
     //Only grab the last 4 years worth of RMAs 
     .Where(r => r.CreatedDate.Year > DateTime.Now.Year - 4) 
     // Group all records by problem  
     .GroupBy(r => new { Problem = r.Problem }) 
     .Select(grouping => new 
      { 
       Problem = grouping.Key.Problem, 
       Occurrences = quarters.Select(quarter => new 
        { 
         Year = quarter.Key.Year, 
         Quarter = quarter.Key.Quarter, 
         Count = grouping 
           .GroupBy(record => new 
           { 
            Year = record.CreatedDate.Year, 
            Quarter = ((record.CreatedDate.Month)/3) 
           }) 
           .Where(record => 
            record.Key.Year == quarter.Key.Year 
            && record.Key.Quarter == quarter.Key.Quarter 
           ).Count() 
        }).ToArray() 
      })); 

更新:由於JamieSee用於與例如JSON輸出更新:

這是一個N實施例的JSON輸出:

[{"Problem":"P","Occurrences":[{"Year":2012,"Quarter":4,"Count":2},{"Year":2012,"Quarter":2,"Count":1},{"Year":2012,"Quarter":1,"Count":1}]},{"Problem":"Q","Occurrences":[{"Year":2012,"Quarter":3,"Count":1},{"Year":2012,"Quarter":2,"Count":1},{"Year":2012,"Quarter":1,"Count":1}]}] 
+0

嗨,Jon,我添加了一個由你的代碼生成的實際JSON的例子。看起來你和我有幾乎相同的想法。 – JamieSee

+0

@JamieSee - 謝謝!我從來沒有使用過JSON,因此我修改了代碼以將結果存儲在變量中,並將其打印到控制檯以查看它是否看起來像正確的結構。我沒有機會看到實際的Json.Encode調用是否有效。 –

+0

你的回答並不完全回答這個問題?第二部分詢問有關返回宿舍的信息,沒有任何問題,您的解決方案不會這樣做。 –

0

下面是完整的重述,以滿足您所有條件:

public static IEnumerable<DateTime> GetQuarterDates() 
{ 
    for (DateTime quarterDate = DateTime.Now.AddYears(-4); quarterDate <= DateTime.Now; quarterDate = quarterDate.AddMonths(3)) 
    { 
     yield return quarterDate; 
    } 
} 

public static void RunSnippet() 
{ 
    var RMAs = new[] { 
     new { Problem = "P", CreatedDate = new DateTime(2012, 6, 2) }, 
     new { Problem = "P", CreatedDate = new DateTime(2011, 12, 7) }, 
     new { Problem = "P", CreatedDate = new DateTime(2011, 12, 8) }, 
     new { Problem = "P", CreatedDate = new DateTime(2011, 8, 1) }, 
     new { Problem = "P", CreatedDate = new DateTime(2011, 4, 1) }, 
     new { Problem = "Q", CreatedDate = new DateTime(2011, 11, 11) }, 
     new { Problem = "Q", CreatedDate = new DateTime(2011, 6, 6) }, 
     new { Problem = "Q", CreatedDate = new DateTime(2011, 3, 3) } 
    }; 

    var quarters = GetQuarterDates().Select(quarterDate => new { Year = quarterDate.Year, Quarter = Math.Ceiling(quarterDate.Month/3.0) }); 

    var rmaProblemQuarters = from rma in RMAs 
      where rma.CreatedDate > DateTime.Now.AddYears(-4) 
      group rma by rma.Problem into rmaProblems 
      select new { 
          Problem = rmaProblems.Key, 
          Quarters = (from quarter in quarters 
             join rmaProblem in rmaProblems on quarter equals new { Year = rmaProblem.CreatedDate.Year, Quarter = Math.Ceiling(rmaProblem.CreatedDate.Month/3.0) } into joinedQuarters 
             from joinedQuarter in joinedQuarters.DefaultIfEmpty() 
             select new { 
                 Year = quarter.Year, 
                 Quarter = quarter.Quarter, 
                 Count = joinedQuarters.Count() 
                }) 
         }; 

    string json = System.Web.Helpers.Json.Encode(rmaProblemQuarters); 
    Console.WriteLine(json); 
} 

其中產量:

[{"Problem":"P","Quarters":[{"Year":2008,"Quarter":2,"Count":0},{"Year":2008,"Quarter":3,"Count":0},{"Year":2008,"Quarter":4,"Count":0},{"Year":2009,"Quarter":1,"Count":0},{"Year":2009,"Quarter":2,"Count":0},{"Year":2009,"Quarter":3,"Count":0},{"Year":2009,"Quarter":4,"Count":0},{"Year":2010,"Quarter":1,"Count":0},{"Year":2010,"Quarter":2,"Count":0},{"Year":2010,"Quarter":3,"Count":0},{"Year":2010,"Quarter":4,"Count":0},{"Year":2011,"Quarter":1,"Count":0},{"Year":2011,"Quarter":2,"Count":1},{"Year":2011,"Quarter":3,"Count":1},{"Year":2011,"Quarter":4,"Count":2},{"Year":2011,"Quarter":4,"Count":2},{"Year":2012,"Quarter":1,"Count":0},{"Year":2012,"Quarter":2,"Count":1}]},{"Problem":"Q","Quarters":[{"Year":2008,"Quarter":2,"Count":0},{"Year":2008,"Quarter":3,"Count":0},{"Year":2008,"Quarter":4,"Count":0},{"Year":2009,"Quarter":1,"Count":0},{"Year":2009,"Quarter":2,"Count":0},{"Year":2009,"Quarter":3,"Count":0},{"Year":2009,"Quarter":4,"Count":0},{"Year":2010,"Quarter":1,"Count":0},{"Year":2010,"Quarter":2,"Count":0},{"Year":2010,"Quarter":3,"Count":0},{"Year":2010,"Quarter":4,"Count":0},{"Year":2011,"Quarter":1,"Count":1},{"Year":2011,"Quarter":2,"Count":1},{"Year":2011,"Quarter":3,"Count":0},{"Year":2011,"Quarter":4,"Count":1},{"Year":2012,"Quarter":1,"Count":0},{"Year":2012,"Quarter":2,"Count":0}]}] 
+0

與JonSenchyna類似,您的答案不能解決問題的第二部分。 –

+0

已更新答案以符合空白季度標準。另外,我已經用Linq語法重申它,而不是Linq方法調用,因爲它變得很難閱讀。 – JamieSee

相關問題