C#如何从父子列表中获取ID列表

时间:2017-08-02 09:21:44

标签: c# entity-framework linq

我有一个包含父子关系的任务列表。关系不断变化。由于列表结构是扁平的,我需要通过DisplayOrder列对每个任务进行排序。

字段:

TaskID - Title   -    ParentID  -  DisplayOrder
1        A Task       Null      -     1
2        B Task       Null            3
3        C - A        1               2
4        D - B        2               4

我可以想象,在任何关系发生变化之后,我会以每个子ID在其自己的Parent-ID下的方式获取所有任务ID,然后以当前序列更新这些ID中的DisplayOrder。

但我不确定这在c#中是如何实现的。请就此提出建议。

2 个答案:

答案 0 :(得分:2)

您正在处理树结构,因此这需要递归。

如果我理解正确,你想用以下方式枚举任务(显然是伪代码):

foreach(rootTask in all-tasks-having-no-parent)
{
    yield return rootTask;
    foreach(childTask in rootTask's-direct-children)
    {
        do-the-same-with-childTask-and-its-children-as-I'm-doing-with-rootTask;
    }
}

所以让我们实现递归方法:

public static class MyExtensions
{
    /// <summary>
    /// Traverse a hierachy of items depths-first.
    /// </summary>
    /// <param name="source">The item source.</param>
    /// <param name="childrenGetter">Function to get the direct children of an item.</param>
    /// <returns>The items in <paramref name="source"/>, each recursively followed by it's descendants.</returns>
    public static IEnumerable<TSource> DepthFirst<TSource>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TSource>> childrenGetter)
    {
        foreach(var item in source)
        {
            yield return item;
            foreach (var descendant in childrenGetter(item).DepthFirst(childrenGetter))
                yield return descendant;
        }
    }
}

我们现在需要的只是了解根任务以及如何获取给定任务的子任务。使用Lookup最容易和最有效地完成这两者,var tasks = new[] { new Task { Id = 1, Title = "A", ParentId = null }, new Task { Id = 2, Title = "B", ParentId = null }, new Task { Id = 3, Title = "C", ParentId = 1 }, new Task { Id = 4, Title = "D", ParentId = 2 }, }; var childrenByParentId = tasks.ToLookup(t => t.ParentId); 本质上是一个值类型为IEnumerable的字典。

DisplayOrder

现在,您可以按所需顺序枚举任务并分配var order = 0; foreach (var task in childrenByParentId[null].DepthFirst(parent => childrenByParentId[parent.Id])) task.DisplayOrder = ++order;

myArray.forEach(function (item, index, myArray) {
  console.log(item.name + ' costs ' + item.price)
})

答案 1 :(得分:0)

看起来像树结构。 你应该安装这样的东西:

      root 
        |
  ----------------
  |              |
A Task        B Task 
  |              |
C - A         D - B  

之后你应该进行深度优先搜索来创建  DisplayOrder。 点击此处:https://en.wikipedia.org/wiki/Depth-first_search

编辑:葡萄牙语版本有一个很好的形象,有助于:https://pt.wikipedia.org/wiki/Busca_em_profundidade#/media/File:Depthfirst.png

然后你会得到这个:

    root (0)
        |
  ----------------
  |              |
A Task (1)    B Task (3)
  |              |
C - A  (2)    D - B  (4)

希望这有帮助。