C# C语言中一组相关对象中的多棵树#

C# C语言中一组相关对象中的多棵树#,c#,linq,C#,Linq,我们正在创建一个博客应用程序,需要将所有评论组织到一个层次结构树中 事实上,我认为这是多树结构 注释类的简化版本: Class Comment { public string CommentId {get; set;} public string ParentCommentId {get; set;} public string Comment{get; set;} } 当有人做出新评论(比如a)时,ParentCommentId将为空。很像树根 当有人回复该评论(a)时,将创建一个

我们正在创建一个博客应用程序,需要将所有评论组织到一个层次结构树中

事实上,我认为这是多树结构

注释类的简化版本:

Class Comment
{
 public string CommentId {get; set;}
 public string  ParentCommentId {get; set;}
 public string  Comment{get; set;}
}
当有人做出新评论(比如a)时,ParentCommentId将为空。很像树根

当有人回复该评论(a)时,将创建一个新的评论(比如b),它将继承主评论的Id作为其ParentCommentId

然后,如果有人回复这个新评论(b),将创建一个新评论(比如c),并将第二个评论(b)Id作为其ParentCommentId

基本上是一个多树结构,每个树根是某人创建新评论(a)的结果(即不回复其他人的评论(b,c)

一些天才能否告诉我们,我们如何能够高效地将所有注释捕获到这样一个结构中,最好使用Linq


非常感谢

我相信,通过使用递归linq查询,您看起来像这样:

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    const int maxDepth=3;

    class Comment
    {
        public string CommentId {get; set;}
        public string  ParentCommentId {get; set;}
        public string  CommentText{get; set;}
        public List<Comment> ChildComments { get; set; }
    }

    public static void Main()
    {

         List<Comment> comments = new List<Comment>()
        {


            new Comment () { CommentId = "1", CommentText = "Comment 1", ParentCommentId = ""},
            new Comment () { CommentId = "2", CommentText = "Comment 2", ParentCommentId = ""},


            new Comment () { CommentId = "3", CommentText = "Sub Comment 1 of 1", ParentCommentId = "1"},
            new Comment () { CommentId = "4", CommentText = "Sub Comment 1 of 2", ParentCommentId = "2"},

            new Comment () { CommentId = "5", CommentText = "Sub Comment 2 of 1", ParentCommentId = "3"},


            new Comment () { CommentId = "6", CommentText = "Sub Comment 1 of 5", ParentCommentId = "5"},
            new Comment () { CommentId = "7", CommentText = "Sub Comment 1 of 6", ParentCommentId = "6"},
             new Comment () { CommentId = "8", CommentText = "Sub Comment 1 of 7", ParentCommentId = "7"},  
        };


        var formattedList =  GetChildComments(comments, "", 1);

        Console.WriteLine(formattedList.Count()); //2
        Console.WriteLine(formattedList[0].ChildComments.Count()); //1
        Console.WriteLine(formattedList[1].ChildComments.Count());//1

        Console.WriteLine(formattedList[0].ChildComments[0].ChildComments.Count());//1


    }

    private static List<Comment> GetChildComments(List<Comment> comments, string parentCommentId, int depth)
    {
        if(depth>maxDepth)
        {
            return new List<Comment>();
        }

        return comments
                .Where(c => c.ParentCommentId == parentCommentId)
                .Select(c => new Comment { 
                   CommentId = c.CommentId, 
                              CommentText = c.CommentText, 
                              ParentCommentId = c.ParentCommentId, 
                              ChildComments = GetChildComments(comments, c.CommentId,  depth+1)})
                .ToList();
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
公共课程
{
常量int maxDepth=3;
课堂评论
{
公共字符串CommentId{get;set;}
公共字符串ParentCommentId{get;set;}
公共字符串注释文本{get;set;}
公共列表ChildComments{get;set;}
}
公共静态void Main()
{
列表注释=新列表()
{
新注释(){CommentId=“1”,CommentText=“Comment 1”,ParentCommentId=”“},
新注释(){CommentId=“2”,CommentText=“Comment 2”,ParentCommentId=”“},
新注释(){CommentId=“3”,CommentText=“子注释1/1”,ParentCommentId=“1”},
新注释(){CommentId=“4”,CommentText=“子注释1/2”,ParentCommentId=“2”},
新注释(){CommentId=“5”,CommentText=“子注释2/1”,ParentCommentId=“3”},
新注释(){CommentId=“6”,CommentText=“第1条注释,共5条注释”,ParentCommentId=“5”},
新注释(){CommentId=“7”,CommentText=“第1条注释,共6条注释”,ParentCommentId=“6”},
新注释(){CommentId=“8”,CommentText=“第1条注释,共7条注释”,ParentCommentId=“7”},
};
var formattedList=GetChildComments(comments,“,1);
Console.WriteLine(formattedList.Count());//2
Console.WriteLine(formattedList[0].ChildComments.Count());//1
Console.WriteLine(formattedList[1].ChildComments.Count());//1
Console.WriteLine(formattedList[0].ChildComments[0].ChildComments.Count());//1
}
私有静态列表GetChildComments(列表注释、字符串parentCommentId、整数深度)
{
如果(深度>最大深度)
{
返回新列表();
}
回复评论
。其中(c=>c.ParentCommentId==ParentCommentId)
.Select(c=>newcomment{
CommentId=c.CommentId,
CommentText=c.CommentText,
ParentCommentId=c.ParentCommentId,
ChildComments=GetChildComments(comments,c.CommentId,深度+1)})
.ToList();
}
}

您可以看到它在

上工作吗?您从数据库中提取这些注释吗?@Jason它们来自何处?它们只是一个注释对象流。可以来自数据库,可以来自csv,可以来自Lucene索引等。非常感谢。有没有一种简单的方法来限制每个根树(即,主注释中的Parentid为空)指向特定数量的子树。例如3、4、5或其他。您能再详细说明一下吗?我不清楚您所说的“限制每个根…”是什么意思.Hi.每个使用空白ParentId创建的新评论都可以称之为Master。创建新评论时,我们可以有几个Master。当用户回复时,这些Master中的每一个都会启动一个chil树链。我想根据一个图限制此树结构的深度。因此,如果此图为3,我们可以拥有Master,即第一个子树,然后是第一个子树的第一个子树。感谢您,现在您可以将深度传递给“GetChildComments”以实现此目的,我将在访问我的笔记本电脑后更新代码。请参阅使用深度更新的代码,您需要更改顶部定义的maxDepth常量值,您可以在此处看到工作示例: