C#でスレッドコメントシステムを構築する方法は?助けて
-
22-07-2019 - |
質問
私のウェブサイト用にスレッドコメントシステムを構築していますが、問題に遭遇しました...
IDフィールドと親IDフィールドを持つデータベースから取得したリストがあります。親IDフィールドはnullにできますが、IDフィールドはnullにはなりません。
これはスレッド化されたコメントシステムであるため、IDが一番上のリストに整理されますが、親IDが存在する場合は、IDの下に挿入されます。その後、これは無限に続くこともあります。したがって、2番目のレベルにもIDがあり、その下にそのIDの親IDを持つアイテムを挿入したいです。
例:
--- 1。何とか
-------- 2。 Blah Blah-> ParentID = 1
----------- 3。 Blah Blah-> parentID = 2
-------------- 4. Blah Blah-> parentID = 3
----------- 3.Blah Blah-> parentID = 2
-------- 2。 Blah Blah-> 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のコメントは、2番目ではなく最初のthreadID = 3要素の下にあると言ってどうですか?
あなたが望んでいることの詳細について多くを知ることなく、一般的に私はコメント付きのデータ構造を考慮します:
- CommentID:このエンティティのID
- RootID:スレッドのルート要素のID(したがって、スレッドのすべてのコメントを簡単に取得できます)
- ParentID:このコメントの親のCommentID。ルート要素の場合はnull
- タイムスタンプ:または、1つの親内の子コメントを適切にソートできるようにするもの。
それを考えると、もしそれがあなたが心配しているのであれば、インデントレベルを計算するのはかなり簡単だろう。それが便利に思える場合は、さらに詳しく説明します。そうでない場合は、質問を明確にしてください。
再帰関数が必要です。また、リストをどのように走査しているように見えるかに基づいて、(親IDではなく)IDとChildIDを保存することをお勧めします。このように、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();
}
}