比较3个列表之间的值,并将第一个列表中的缺失值添加到剩余的2个列表中 - C#

时间:2017-11-11 12:59:05

标签: c# asp.net entity-framework list linq

我需要准备一张图表,其中我需要显示3行。

一个用于显示一周的新问题,一个用于一周的已结束问题,第三个用于从第一周到上一周的总累积未决问题。

出于这个原因,我准备了一个查询,并且能够成功创建2个单独的列表 - 一个列表维护每周新发布的计数,第二个列表维护每周关闭的问题计数。

以下是第一个列表的示例数据(维护新问题的列表):

        [0]: { Week = {6/14/2015 12:00:00 AM}, Count = 1 }
        [1]: { Week = {3/5/2017 12:00:00 AM}, Count = 1 }
        [2]: { Week = {5/21/2017 12:00:00 AM}, Count = 4 }
        [3]: { Week = {6/4/2017 12:00:00 AM}, Count = 7 }
        [4]: { Week = {6/11/2017 12:00:00 AM}, Count = 4 }
        [5]: { Week = {6/25/2017 12:00:00 AM}, Count = 7 }
        [6]: { Week = {7/9/2017 12:00:00 AM}, Count = 3 }

根据以上数据,我得到特定一周的未决问题总数。

注意:对于这两个列表,周值包含星期日的日期。 因为我需要在周一开始一周,同时在图表中显示数据。

类似地,对于第二个列表的样本数据(一个维持已关闭的问题):

[0]: { Week = {12/13/2015 12:00:00 AM}, Count = 1 }
[1]: { Week = {7/9/2017 12:00:00 AM}, Count = 3 }
[2]: { Week = {6/18/2017 12:00:00 AM}, Count = 2 }
[3]: { Week = {7/23/2017 12:00:00 AM}, Count = 8 }
[4]: { Week = {10/1/2017 12:00:00 AM}, Count = 6 }
[5]: { Week = {8/6/2017 12:00:00 AM}, Count = 3 }
[6]: { Week = {9/17/2017 12:00:00 AM}, Count = 1 }

根据以上数据,我得到特定一周的已结束问题的总数。

以下是这些列表的代码:

var openIssuesList = getDetails.Where(x => x.ChangedTo == "Open").Select(x => new { Week = x.Date.AddDays(x.Date.DayOfWeek == DayOfWeek.Sunday ? 0 : 7 - (int)x.Date.DayOfWeek).Date, Detail = x }).GroupBy(x => x.Week).Select(x => new { Week = x.Key, Count = x.Count() }).ToList();


var closedIssuesList = getDetails.Where(x => x.ChangedTo == "Closed").Select(x => new { Week = x.Date.AddDays(x.Date.DayOfWeek == DayOfWeek.Sunday ? 0 : 7 - (int)x.Date.DayOfWeek).Date, Detail = x }).GroupBy(x => x.Week).Select(x => new { Week = x.Key, Count = x.Count() }).ToList();

正如我之前提到的,我需要使用从这些列表中获得的数据准备每周折线图。 现在剩下的最后一块是使用我准备好的第三个列表将缺失的周值填入这两个列表中。

我准备了一个名单 datesList ,其中包含指定日期范围之间的所有日期(在星期日)。

以下是此列表的示例数据:

[0]: {6/14/2015 12:00:00 AM}
[1]: {6/21/2015 12:00:00 AM}
[2]: {6/28/2015 12:00:00 AM}
[3]: {7/5/2015 12:00:00 AM}
[4]: {7/12/2015 12:00:00 AM}
[5]: {7/19/2015 12:00:00 AM}
[6]: {7/26/2015 12:00:00 AM}
//And so on ....

说明:

  1. 我需要将 datesList 中的周值与openIssuesList的周值进行比较。
  2. 如果openIssuesList中也存在来自 datesList 的周值,则不要添加/更改此类列表值。
  3. 如果openIssuesList中不存在星期值 datesList ,则在openIssuesList列表中添加此类周值,并将其Count值设置为0。
  4. 对closedIssuesList重复相同的步骤。 (如果这个过程可以同时进行,避免重复,请建议)
  5. 所以从以上提供的3个列表的示例数据中可以看出新更新的 openIssuesList 列表应该如何:(仅显示少量记录)

    [0]: { Week = {6/14/2015 12:00:00 AM}, Count = 1 } // Exisiting record hence no change for this record
    [1]: { Week = {6/21/2015 12:00:00 AM}, Count = 0 } // As this date was not existing initially it's been added with Count value set to 0
    [2]: { Week = {6/28/2015 12:00:00 AM}, Count = 0 } // As this date was not existing initially it's been added with Count value set to 0
    
    //and so on....
    

    相同的逻辑适用于closedIssuesList。

    所以 datesList 是一种“主列表”,我们需要将其他列表与此列表进行比较。如果其他列表中缺少 datesList 中存在的周值,则将此周值添加到 Count 值设置为0的其他列表中。

    编辑

    最初位于列表 openIssuesList & closedIssuesList 我没有选择这些问题的ID。只检索了问题的周和计数。

    因此,为了选择这些ID,我更新了这两个列表的逻辑,如下所示:

     var openIssuesList = getDetails.Where(x => x.ChangedTo == "Open").Select(x => new { Week = x.Date.AddDays(x.Date.DayOfWeek == DayOfWeek.Sunday ? 0 : 7 - (int)x.Date.DayOfWeek).Date, Detail = x }).GroupBy(x => x.Week).Select(x => new { Week = x.Key, Count = x.Count(), Issues = x.Select(y => y.Detail.IssueID).ToArray() }).ToList();                    
    
     var closedIssuesList = getDetails.Where(x => x.ChangedTo == "Closed").Select(x => new { Week = x.Date.AddDays(x.Date.DayOfWeek == DayOfWeek.Sunday ? 0 : 7 - (int)x.Date.DayOfWeek).Date, Detail = x }).GroupBy(x => x.Week).Select(x => new { Week = x.Key, Count = x.Count(),Issues = x.Select(y => y.Detail.IssueID).ToArray() }).ToList();
    

    因此我只是添加了这个:

    Issues = x.Select(y => y.Detail.IssueID).ToArray()
    

    进入我的最终Select子句,它也有助于获取IssueID(最初我们只是获取了这些IssuesID的计数)

    到目前为止一切顺利。

    但现在我想将这些IssuesID包含在 @stybl 提供的解决方案中。

    那么我应该如何修改我的逻辑以适应 @stybl的解决方案中的IssueID。

    尝试这显然会出错:

     openIssuesList.Concat(datesList.Where(date => !openIssuesList.Any(pair => pair.Week == date)).Select(date => new { Week = date, Count = 0, Issues = x.Select(y => y.Detail.IssueID).ToArray() });
    

    如何为此部分选择合适的IssueID?

1 个答案:

答案 0 :(得分:2)

这应该适合你:

.checker

我们在这里做的是根据日期得到两个列表的交叉的逆。从那里我们选择带有数据的匿名对象,最后将生成的枚举附加到openIssuesList.Concat(datesList.Where(date => !openIssuesList.Any(pair => pair.Week == date)) .Select(date => new { Week = date, Count = 0 });

同样适用于openIssuesList

closedIssuesList