在 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 字段都是空白的吗?这是我打算使用以下规则查找的值:
我只需要更新具有 parent 的任务。所有 top-level parent(以 TemplateParentId == null
表示)都可以。
我知道给定子任务的 TemplateParentId
并且我知道 DueDate
。截止日期需要在 parent 的下一个截止日期之前。例如,如果子任务的 TemplateParentId == 1
那么它的 parent 有 TemplateId == 1
而它的 parent 将是最接近未来或相同日期的那个。
具有相同 TemplateId 的行永远不会有相同的日期。它们在连续日期方面总是不同的。
例如使用示例数据,前两行具有相同的 TemplateId
,但它们的截止日期相差一年。基本上,这是每年需要完成的相同任务。第 3、4 和 5 行是具有相同模板 parent,但截止日期不同的子任务。这些任务需要在 parent 到期之前或当天完成。例如,任务 3 的截止日期为 2020 年 6 月,在 2 个可能的 parent 中,下一个最接近的日期是 2020 年 12 月。因此,ParentId
应该是 1。任务 5 的完成日期为2021 年 12 月 31 日和下一个最接近的 parent 截止日期是同一日期,因此 ParentId
应该是 2.
列表排名不分先后。
希望这是有道理的。我不确定如何编写代码,但这是我未经测试的主要 伪 代码:
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
}
}
我有一个任务和子任务列表(使用 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 字段都是空白的吗?这是我打算使用以下规则查找的值:
我只需要更新具有 parent 的任务。所有 top-level parent(以
TemplateParentId == null
表示)都可以。我知道给定子任务的
TemplateParentId
并且我知道DueDate
。截止日期需要在 parent 的下一个截止日期之前。例如,如果子任务的TemplateParentId == 1
那么它的 parent 有TemplateId == 1
而它的 parent 将是最接近未来或相同日期的那个。具有相同 TemplateId 的行永远不会有相同的日期。它们在连续日期方面总是不同的。
例如使用示例数据,前两行具有相同的
TemplateId
,但它们的截止日期相差一年。基本上,这是每年需要完成的相同任务。第 3、4 和 5 行是具有相同模板 parent,但截止日期不同的子任务。这些任务需要在 parent 到期之前或当天完成。例如,任务 3 的截止日期为 2020 年 6 月,在 2 个可能的 parent 中,下一个最接近的日期是 2020 年 12 月。因此,ParentId
应该是 1。任务 5 的完成日期为2021 年 12 月 31 日和下一个最接近的 parent 截止日期是同一日期,因此ParentId
应该是 2.列表排名不分先后。
希望这是有道理的。我不确定如何编写代码,但这是我未经测试的主要 伪 代码:
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
}
}