如何在 C# 中构建线程评论系统?帮助
-
22-07-2019 - |
题
我正在为我的网站构建线程评论系统,但遇到了问题......
我有一个从数据库中提取的列表,其中包含 ID 字段和父 ID 字段。父 ID 字段可以为空,但 ID 字段永远不会为空。
由于这将是一个线程评论系统,因此我将列表组织到 ID 位于顶部的位置,但如果存在父 ID,则它将插入到该 ID 下。那么这也可以无限持续下去。因此,第二级现在也有一个 ID,并且我想在其下方插入具有该 ID 的父 ID 的任何项目。
例如:
---1.废话
--------2。巴拉巴拉 -> ParentID=1
-----------3.巴拉巴拉->parentID=2
-------------- 4.巴拉巴拉->parentID=3
----------- 3.Blah Blah ->parentID=2
--------2。巴拉巴拉->parentID=1
我认为你说对了。
这就是我到目前为止所拥有的......
List<comment> finalList = new List<comment>();
for (int i = 0; i < getComments.Count(); i++)
{
string item = getComments[i].parentComment;
getComments[i].threadID = 1;
finalList.Add(getComments[i]);
for (int ii = 0; ii < getComments.Count(); ii++)
{
if (getComments[ii].commentID == item)
{
getComments[ii].threadID = 2;
finalList.Add(getComments[i]);
}
}
}
看起来似乎是对了一半,但事实并非如此......ThreadID 当然是它被植入到右侧的距离。
解决方案 2
感谢大家的帮助球员。我欣赏它。
我虽然发现通过写绝对一切为它的人的东西。
http://www.scip.be/index.php?Page=ArticlesNET23
其他提示
假设您使用的是 Count() 扩展方法而不是 Count 属性(这本身效率稍低;不过,从使用 foreach 开始会更好)您可能正在使用 .NET 3.5。
我认为我没有完全理解您的方案 - 例如,您图中带有 threadID=4 的注释位于第一个 threadID=3 元素而不是第二个元素下,有什么可说的?
在不太了解您所追求的细节的情况下,一般来说,我会考虑使用以下注释数据结构:
- 评论ID:该实体的 ID
- 根ID:线程根元素的 ID(因此您可以轻松获取线程的所有评论)
- 家长 ID:此评论的父元素的 CommentID,如果是根元素则为 null
- 时间戳:或者其他可以让父母一方的孩子评论得到适当排序的东西。
鉴于此,如果您担心的是缩进级别,那么计算出缩进级别将相当容易。如果这听起来有用,我可以详细说明 - 如果没有,请澄清问题。
您需要一个递归函数,并根据它的外观像你遍历列表,它很可能是更好的存储ID和childID的(而不是父ID)。通过这种方式,递归函数可以结束遍历时childID的== NULL。
这可能工作:
class Program
{
static void Main(string[] args)
{
CommentCollection collection=new CommentCollection();
Comment c1=new Comment("Blah",1,0,collection);
Comment c2=new Comment("Blah blah",2,1,collection);
Comment c3=new Comment("Blah blah", 3, 2, collection);
Console.WriteLine(collection);
}
}
[DebuggerDisplay("{id}-{parentId}: {text}")]
class Comment:IEnumerable<Comment>
{
private readonly CommentCollection collection;
private readonly int parentId;
public Comment(string text, int id, int parentId, CommentCollection collection)
{
Id = id;
this.parentId = parentId;
collection.Add(this);
this.collection = collection;
this.text = text;
}
public Comment Parent
{
get
{
if (parent == null)
{
parent = parentId == 0 ? null : collection[parentId];
}
return parent;
}
}
private Comment parent;
private readonly string text;
public int Id{ get; private set;}
public IEnumerator<Comment> GetEnumerator()
{
return collection.Where(c => c.Parent == this).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public int Level
{
get { return Parent == null ? 0 : Parent.Level + 1; }
}
public override string ToString()
{
return Parent == null ? text : Parent + " > " + text;
}
public string ToString(bool tree)
{
if (!tree)
{
return ToString();
}
else
{
StringBuilder output = new StringBuilder();
output.AppendLine(new string(' ', Level) + ToString(false));
foreach (Comment comment in this)
{
output.AppendLine(comment.ToString(true));
}
return output.ToString();
}
}
}
class CommentCollection:IEnumerable<Comment>
{
public void Add(Comment comment)
{
comments.Add(comment.Id,comment);
}
public Comment this[int id]
{
get { return comments[id]; }
}
private readonly Dictionary<int,Comment> comments=new Dictionary<int, Comment>();
public IEnumerator<Comment> GetEnumerator()
{
return comments.Select(p => p.Value).GetEnumerator();
}
public IEnumerable<Comment> GetTopLevel()
{
return comments.Where(c => c.Value.Parent == null).
Select(c => c.Value);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public override string ToString()
{
StringBuilder output=new StringBuilder();
foreach (Comment comment in GetTopLevel())
{
output.AppendLine(comment.ToString(true));
}
return output.ToString();
}
}