递归LINQ查询:选择项及其所有子项和子项的子项。

16

有没有一种方法可以编写一个LINQ(或过程式样式)查询,可以选择一个项目和所有子项,并用一个查询获取它们?我有一个实体:

public class Comment
{
   public int Id {get;set;}
   public int ParentId {get;set;}
   public int Text {get;set;}
}

我有一个ID,所以我想选择具有该ID的评论及其所有子评论和子评论的子评论。

1
-2
--3
-4
-5
--6
2
3
如果ID == 1,则我想要1、2、3、4、5、6的列表。

1
是 LINQ to SQL、LINQ to Entities 还是 LINQ to Objects? - MarcinJuraszek
3个回答

24
   public class Comment
    {
        public int Id { get; set; }
        public int ParentId { get; set; }
        public string Text { get; set; }        
        public List<Comment> Children { get; set; }
    }

    class Program
    {
        static void Main()
        {
        List<Comment> categories = new List<Comment>()
            {
                new Comment () { Id = 1, Text = "Item 1", ParentId = 0},
                new Comment() { Id = 2, Text = "Item 2", ParentId = 0 },
                new Comment() { Id = 3, Text = "Item 3", ParentId = 0 },
                new Comment() { Id = 4, Text = "Item 1.1", ParentId = 1 },
                new Comment() { Id = 5, Text = "Item 3.1", ParentId = 3 },
                new Comment() { Id = 6, Text = "Item 1.1.1", ParentId = 4 },
                new Comment() { Id = 7, Text = "Item 2.1", ParentId = 2 }
            };

            List<Comment> hierarchy = new List<Comment>();
            hierarchy = categories
                            .Where(c => c.ParentId == 0)
                            .Select(c => new Comment() { 
                                  Id = c.Id, 
                                  Text = c.Text, 
                                  ParentId = c.ParentId, 
                                  Children = GetChildren(categories, c.Id) })
                            .ToList();

            HieararchyWalk(hierarchy);

            Console.ReadLine();
        }

        public static List<Comment> GetChildren(List<Comment> comments, int parentId)
        {
            return comments
                    .Where(c => c.ParentId == parentId)
                    .Select(c => new Comment { 
                        Id = c.Id, 
                        Text = c.Text, 
                        ParentId = c.ParentId, 
                        Children = GetChildren(comments, c.Id) })
                    .ToList();
        }

        public static void HieararchyWalk(List<Comment> hierarchy)
        {
            if (hierarchy != null)
            {
                foreach (var item in hierarchy)
                {
                    Console.WriteLine(string.Format("{0} {1}", item.Id, item.Text));
                    HieararchyWalk(item.Children);
                }
            }
        }

我在这段代码中还需要一个帮助,我在评论类中有成员ObjectType。我想根据ObjectType对层次列表进行分组{ObjectType =文件夹、文件}。 - Kalidoss M
我不完全理解你想要实现什么。你应该创建一个带有示例输入/期望输出的问题... - Branimir

13
IEnumerable<Comment> GetChild(int id)
{
    return table.Where(x => x.ParentID == id || x.Id== id)
                .Union(table.Where(x => x.ParentID == id)
                            .SelectMany(y => GetChild(y.Id))
    );
}

5

您的评论类可以看作是一张图,您的问题可以视为图遍历问题

您无法通过linq定义递归问题,但可以通过简单的递归方法轻松解决该问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接