c# - 使用 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 字段都是空白的?这是我打算使用以下规则找到的值:
我只需要更新具有父级的任务。所有顶级父母(由 表示
TemplateParentId == null
)都可以。我知道
TemplateParentId
给定子任务的 并且我知道DueDate
. 截止日期必须在父母的下一个截止日期之前。例如,如果子任务是TemplateParentId == 1
它的父母TemplateId == 1
,那么它的父母将是最接近未来或同一日期的那个。具有相同 TemplateId 的行将永远不会具有相同的日期。它们在连续日期方面总是不同的。
例如,使用示例数据,前 2 行具有相同的
TemplateId
,但它们的截止日期相隔一年。基本上,这是每年都需要完成的相同任务。第 3、4 和 5 行是具有相同模板父级的子任务,但它们的截止日期不同。这些任务需要在父母到期之前或当天完成。例如,任务 3 应于 2020 年 6 月到期,而在它的 2 个可能的父母中,下一个最接近的日期是 2020 年 12 月。因此,它ParentId
应该是 1。任务 5 将于 2021 年 12 月 31 日完成,下一个最接近的父母到期日期是同一日期,所以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!
}
}
我怎么能做到这一点并且有效率?提前致谢。
解决方案
这凸显了 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
}
}
推荐阅读
- laravel - Laravel 5.6 - 404 虽然定义了路由
- c - 将数字分配给C中的char变量?
- javascript - Javascript/Angular Basics - 从范围中读取一个简单的值
- javascript - 使用 jQuery 的类和值不为空的所有选择列表选项
- swift - 如何子类化 AVCaptureInput 和 AVCaptureInput.Port?
- java - Ant 没有使用我的 JAVA_HOME 来查找 tools.jar
- java - Java - 如何在 if 语句中添加 rgb 值?
- c# - 是否有 api 接口可以与 Unreal 进行材质交换?
- unity3d - 阻止粒子与相机一起滚动(统一)
- sql-server - TSQL 包含有条件的帐户