C# 计数值为0的每小时Groupby计数

C# 计数值为0的每小时Groupby计数,c#,asp.net,list,C#,Asp.net,List,我有一份人员名单,我想每小时登记一次。我使用了下面的GroupBy子句,得到了正确的结果 var persons = lstPerson.GroupBy(x =>(x.CreatedOn.Hour)) .Select(grp => new { total = grp.Count(), key = grp.Key }) .OrderBy(x => x.key)

我有一份人员名单,我想每小时登记一次。我使用了下面的
GroupBy
子句,得到了正确的结果

var persons = lstPerson.GroupBy(x =>(x.CreatedOn.Hour))
                       .Select(grp => new { total = grp.Count(), key = grp.Key })
                       .OrderBy(x => x.key)
                       .ToList();
但我想要每一个小时。它只显示计数所在的值。若在第一个小时内并没有人注册,则列表中不会显示0计数

例如,有人只登记了13、14、15小时(指13:00、14:00和15:00小时),然后它会显示该时间的计数,但不会显示其他时间的计数。

有几个选项:

首先,在代码更改最少的情况下,您只需在每个组中“添加一个”,然后从每个计数中“减去一个”:

var persons = lstPerson
    .Select(x => (x.CreatedOn.Hour))  // Get the hours from the people
    .Concat(Enumerable.Range(0, 24))  // Add an extra copy of each hour
    .GroupBy(h => h)                      // ↓ subtract the extra hours
    .Select(grp => new { total = grp.Count() - 1, key = grp.Key })
    .OrderBy(x => x.key)
    .ToList();
其次,更整洁,但需要替换所有代码,您可以将人员列表加入小时列表:

var persons = Enumerable.Range(0, 24)
    .GroupJoin(
        lstPerson,
        h => h,                  // Correlate the hours in the range
        p => p.CreatedOn.Hour,   // with the hours from each person
        (h, ps) => new { total = ps.Count(), key = h))
    .ToList();    // ↑ This selects one element for each hour in the range

你能告诉我哪一个性能更好吗?谢谢。我想他们很相似。如果您担心性能,请同时运行它们,看看哪一个更快。