首页 > 解决方案 > 使用 C# 中的连续日期识别分层数据中的父级

问题描述

我有一个任务和子任务列表(使用父子关系),这些任务和子任务是使用模板中的连续日期创建的。我需要根据模板父 ID 以及截止日期相对于父截止日期来确定每个任务的父节点。使困惑?让我举例说明。这是我的课:

public class Task
{
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public int TemplateId { get; set; }
    public int? TemplateParentId { get; set; }
    public DateTime DueDate { get; set; }
}

这里有一些数据可以更清楚地理解它:

List<Task> tasks = new List<Task>( );

tasks.Add( new Task { Id = 1, ParentId = null, TemplateId = 1, TemplateParentId = null, DueDate = new DateTime( 2020, 12, 31 ) } );
tasks.Add( new Task { Id = 2, ParentId = null, TemplateId = 1, TemplateParentId = null, DueDate = new DateTime( 2021, 12, 31 ) } );

tasks.Add( new Task { Id = 3, ParentId = null, TemplateId = 2, TemplateParentId = 1, DueDate = new DateTime( 2020, 6, 1 ) } );
tasks.Add( new Task { Id = 4, ParentId = null, TemplateId = 2, TemplateParentId = 1, DueDate = new DateTime( 2021, 6, 1 ) } );
tasks.Add( new Task { Id = 5, ParentId = null, TemplateId = 2, TemplateParentId = 1, DueDate = new DateTime( 2021, 12, 31 ) } );

tasks.Add( new Task { Id = 6, ParentId = null, TemplateId = 3, TemplateParentId = null, DueDate = new DateTime( 2020, 10, 31 ) } );
tasks.Add( new Task { Id = 7, ParentId = null, TemplateId = 4, TemplateParentId = 3, DueDate = new DateTime( 2020, 10, 31 ) } );

根据 TemplateParentId 值,其中 3 个任务是父任务,4 个是子任务。请注意,所有任务的 ParentId 字段都是空白的?这是我打算使用以下规则找到的值:

希望这是有道理的。我不知道如何编码,但这是我未经测试的大部分代码:

foreach( var task in tasks.OrderBy( t => t.DueDate ) )
{
    if ( task.TemplateParentId == null || task.ParentId.HasValue )
    {
        continue;
    }

    var parentId = tasks.Where( t => t.TemplateId == task.TemplateParentId && t.DueDate >= task.DueDate ).Select( t => t.Id ).LastOrDefault( );

    if( parentId > 0 )
    {
        // update the row with the ParentId, but this is not possible because it will alter the collection and an exception will ensue!
    }
}

我怎么能做到这一点并且有效率?提前致谢。

标签: c#parent-childhierarchical-data

解决方案


这凸显了 Stackoverflow 的价值。在撰写问题时,我无意中提出了一个似乎有效的解决方案:

foreach( var task in tasks.OrderBy( t => t.DueDate ) )
{
    if ( task.TemplateParentId == null || task.ParentId.HasValue )
    {
        continue;
    }

    var parentId = tasks.Where( t => t.TemplateId == task.TemplateParentId && t.DueDate >= task.DueDate ).Select( t => t.Id ).FirstOrDefault( );

    if( parentId > 0 )
    {
        // store the value in a dictionary and process the updates afterwards
    }
}

推荐阅读