在 C# 中使用顺序日期识别分层数据中的 parent

Identify parent in hierarchical data using sequential dates in C#

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

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 个任务是 parent 个任务,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!
    }
}

我怎样才能高效地做到这一点?提前致谢。

这突出了 Whosebug 的价值。在做题的时候,无意中想出了一个看似高效的解法:

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