【问题标题】:Get Parent and then Child objects conditionally有条件地获取父对象,然后获取子对象
【发布时间】:2012-07-05 17:46:17
【问题描述】:

我有一个具有以下基本结构的对象列表:

class Person
{
    public int ID {get; set;}
    public bool ShowChildren {get; set;}
    public int ParentID {get; set;}

    // ...many other properties...
}

我需要返回按 ID 排序的 Person 父类列表。如果启用了 ShowChildren 标志,则还返回其父级下的子级,按 ID 排序。

这只有一层深,即孩子不会有孩子。

我可以编写一个 linq 语句来给我所有的父母,但我被困在如何在启用父母的标志时也包括排序的孩子。

var People = PersonList
             .Where(x => x.ParentID == 0)
             .Orderby(x => x.ID)
             .ToList();

【问题讨论】:

  • 您只是想要一个包含所有父母和相关子女的平面列表,还是想要一个孩子在某种程度上“低于”父母的层次结构?
  • 列表的最终排序应该是自己ID还是ParentID再自己ID?我的意思是,孩子应该永远在父母之后吗?
  • 你希望返回的对象是一个列表,孩子紧跟在他们的父母后面?
  • 结果列表将绑定到数据视图,该数据视图需要按父子顺序排列。因此,结果列表应按父母排序,然后按每个父母下的孩子排序。如果这有意义的话。

标签: c# linq c#-4.0 linq-to-objects


【解决方案1】:

抱歉,如果您只想返回父母,除非明确要求(感谢@Rawling!),foreach 循环也不错。

var people = new List<Person>();

PersonList.Sort((a, b) => a.ID - b.ID);

foreach(Person p in PersonList) {
    if(p.ParentID == 0) { // Or whatever value you use to represent it
        people.Add(p);

        if(p.ShowChildren) {
            people.AddRange(PersonList.Where(c => c.ParentID == p.ID));
        }
    }
}

【讨论】:

  • 此代码将导致每个项目至少添加一次,如果他们的父母愿意展示孩子,他们会被添加第二次。
  • @Rawling:是的,这就是我提出问题的意思。你认为它应该是什么样子? :|
  • 我读到“我需要返回 Person 父类的列表......”表示包括所有父母,只有当父母需要时才包括孩子。所以你只会遍历父母,而不是所有的项目。此外,这不会进行任何排序...
【解决方案2】:

您可以在 两个 语句中执行此操作,如下所示:

// Build a lookup: parent ID => whether to show children.
var showChildrenDictionary = PersonList
    .Where(p => p.ParentID = 0)
    .ToDictionary(p => p.ID, p => p.ShowChildren);

// Get the desired list
var orderdedWithAppropriateChildren = PersonList
    // Discard children where not shown
    .Where(p => p.ParentID == 0 || showChildrenDictionary[p.ParentID])
    // Sort so parents and children are together and ordered by the parent
    .OrderBy(p => ((p.ParentID == 0) ? p.ID : p.ParentID))
    // Sort so parent is at start of group
    .ThenBy(p => p.ParentID != 0)
    // Sort so children are in order
    .ThenBy(p => p.ID)
    .ToList();

【讨论】:

    猜你喜欢
    • 2011-01-02
    • 1970-01-01
    • 2017-12-08
    • 2022-12-15
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    相关资源
    最近更新 更多