C# 按父项和子项以及子项的父项排序的订单列表

C# 按父项和子项以及子项的父项排序的订单列表,c#,linq,C#,Linq,我正在试着订购一份应该是这样的清单 母公司 Child1(同时为孩子和家长) 子女2(子女1的子女) 孩子3 在使用包含有关ID、ParentID等信息的类时 我尝试使用LINQ来实现这一点,并尝试了不同的解决方案,但没有人能完全实现,我知道递归函数可以实现(但我真的不喜欢),有人能帮我实现使用LINQ吗 我尝试了这个代码,但是Child2没有出现 List<Person> orderedList = new List<Person>();

我正在试着订购一份应该是这样的清单

  • 母公司
    • Child1(同时为孩子和家长)
      • 子女2(子女1的子女)
    • 孩子3
  • 在使用包含有关ID、ParentID等信息的类时

    我尝试使用LINQ来实现这一点,并尝试了不同的解决方案,但没有人能完全实现,我知道递归函数可以实现(但我真的不喜欢),有人能帮我实现使用LINQ吗

    我尝试了这个代码,但是Child2没有出现

    List<Person> orderedList = new List<Person>();
                persons.ForEach(x => {
                    if (x.ParentID == 0) {
                        orderedList.Add(x);
                        orderedList.AddRange(persons.Where(child => child.ParentID == x.Id));
                    }
                });
    
    List orderedList=new List();
    persons.ForEach(x=>{
    如果(x.ParentID==0){
    orderedList.Add(x);
    orderedList.AddRange(persons.Where(child=>child.ParentID==x.Id));
    }
    });
    
    对于那些投“反对票”的人,请记住,在一开始编程时,没有人是上帝,如果我来到这里,这意味着我要在x小时内努力解决这个问题。而且,如果你认为我的英语不好,我已经知道了,我不是生来就能说一口流利的英语的,但是那些想帮忙的人会帮忙的

    全部代码

            public class Person{
                public int Id { get; set; }
                public string MenuName { get; set; }
                public int? ParentID { get; set; }
                public string isHidden { get; set; }
                public string LinkURL { get; set; }
            }
            public static List<Person> AddPersons(){
                var persons = new List<Person>();
                using (var reader = new StreamReader(@"C:\Users\AceDuk\Desktop\Navigation.csv")){
                    var line = reader.ReadLine(); //Da se izbegne headerot
                    while ((line = reader.ReadLine()) != null){
                        var values = line.Split(';');
    
                        if (values[2] == "NULL") {
                            values[2] = "0";
                        }
    
                        persons.Add(new Person(){
                            Id = Int32.Parse(values[0]),
                            MenuName = values[1],
                            ParentID = Int32.Parse(values[2]),
                            isHidden = values[3],
                            LinkURL = values[4]
                        });
                    }
                }
                persons.RemoveAll(x => x.isHidden == "True"); //Izbrisi gi site sto se hidden ne gi pokazuvaj..
                //persons = persons.OrderBy(x => x.MenuName).ToList(); //Ordered
                persons = persons.OrderBy(x => x.LinkURL).ToList(); //Ordered
                return persons;
            }
            static void Main(string[] args){
                List<Person> persons = AddPersons();
    
                List<Person> orderedList = new List<Person>();
                persons.ForEach(x => {
                    if (x.ParentID == 0) {
                        orderedList.Add(x);
                        orderedList.AddRange(persons.Where(child => child.ParentID == x.Id));
                    }
                });
    
                foreach (var item in orderedList) {
                    Console.WriteLine(item.MenuName);
                }
            }
    
    公共类人物{
    公共int Id{get;set;}
    公共字符串菜单名{get;set;}
    public int?ParentID{get;set;}
    公共字符串isHidden{get;set;}
    公共字符串链接URL{get;set;}
    }
    公共静态列表AddPersons(){
    var persons=新列表();
    使用(var reader=new StreamReader(@“C:\Users\AceDuk\Desktop\Navigation.csv”)){
    var line=reader.ReadLine();//Da se izbegne headerot
    而((line=reader.ReadLine())!=null){
    变量值=行分割(“;”);
    如果(值[2]=“空”){
    值[2]=“0”;
    }
    人员。添加(新人员(){
    Id=Int32.Parse(值[0]),
    MenuName=值[1],
    ParentID=Int32.Parse(值[2]),
    isHidden=值[3],
    LinkURL=值[4]
    });
    }
    }
    persons.RemoveAll(x=>x.ishiden==“True”);//Izbrisi-gi-site将隐藏的ne-gi-pokazuvaj。。
    //persons=persons.OrderBy(x=>x.MenuName.ToList();//有序
    persons=persons.OrderBy(x=>x.LinkURL.ToList();//有序
    返回人员;
    }
    静态void Main(字符串[]参数){
    列出人员=添加人员();
    List orderedList=新列表();
    persons.ForEach(x=>{
    如果(x.ParentID==0){
    orderedList.Add(x);
    orderedList.AddRange(persons.Where(child=>child.ParentID==x.Id));
    }
    });
    foreach(orderedList中的变量项){
    Console.WriteLine(item.MenuName);
    }
    }
    
    通过扩展链表创建双端队列(deque)数据结构:

    public class Deque<T> : LinkedList<T> {
        public void Enqueue(T item) => AddLast(item);
        public T Dequeue() {
            var item = First.Value;
            RemoveFirst();
            return item;
        }
        public void EnqueueRange(IEnumerable<T> items) {
            foreach (var item in items)
                Enqueue(item);
        }
    
        public void Push(T item) => AddFirst(item);
        public T Pop() => Dequeue();
        public void PushRange(IEnumerable<T> items) {
            foreach (var item in items)
                Push(item);
        }
    
        public T Peek() => Last.Value;
    }
    
    最后,使用deque创建工作列表并添加所有根节点:

    var workDeque = new Deque<Person>();
    workDeque.EnqueueRange(persons.Where(p => p.ParentID == 0));
    

    编程不涉及“缩进”。在编程环境中,“缩进”是什么意思?拼写错误,编辑错误:)LINQ在处理分层数据时非常糟糕。有一些不错的选项涉及循环和数据结构(不是LINQ),但您没有解释为什么不喜欢递归选项。递归非常适合您所描述的内容,而相比之下,其他任何东西都可能会很笨拙。我已经使用递归数百次来解决类似的问题。Linq不适合这种类型的代码。我不知道可能是因为我不知道如何递归地执行它。。。我想也许可以从列表中创建第一棵树,然后遍历元素并打印。。
    var workDeque = new Deque<Person>();
    workDeque.EnqueueRange(persons.Where(p => p.ParentID == 0));
    
    var orderedPersons = new List<Person>();
    
    while (workDeque.Count > 0) {
        var nextPerson = workDeque.Dequeue();
        orderedPersons.Add(nextPerson);
        workDeque.PushRange(childrenDictionary[nextPerson.Id]);
    }