Как создать потоковую систему комментариев на C #?Справка
-
22-07-2019 - |
Вопрос
Я создаю потоковую систему комментариев для своего веб-сайта, и я столкнулся с проблемой...
У меня есть список, ИЗВЛЕЧЕННЫЙ ИЗ БАЗЫ ДАННЫХ, в которой есть поле ID и родительское поле ID.Поле родительского идентификатора может быть нулевым, но поле идентификатора НИКОГДА не будет нулевым.
Поскольку это будет потоковая система комментариев, я упорядочиваю список так, чтобы идентификатор был первым, но если родительский идентификатор существует, то он будет вставлен под идентификатором.Тогда это тоже может продолжаться бесконечно.Таким образом, второй уровень теперь также имеет идентификатор, и я хочу вставить под ним любой элемент с родительским идентификатором этого идентификатора.
Например:
---1.Бла - бла
--------2.Бла - бла -бла -> родительский идентификатор=1
-----------3.Бла - бла -бла -> родительский идентификатор=2
-------------- 4.Бла - бла -бла -> родительский идентификатор=3
----------- 3.Бла-бла -бла -> Родительский идентификатор=2
--------2.Бла - бла -бла -> родительский идентификатор=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]);
}
}
}
Кажется, что это сортирует ситуацию наполовину, но не по-настоящему...Идентификатор потока - это, конечно, то, как далеко он помещается справа.
Решение 2
Спасибо всем за вашу помощь, ребята.Я действительно ценю это.
Тем не менее, я нашел кое-что от парня, который написал для этого абсолютно все.
http://www.scip.be/index.php?Page=ArticlesNET23
Другие советы
Учитывая, что вы используете метод расширения Count() вместо свойства Count (что само по себе является небольшой неэффективностью;хотя для начала было бы лучше использовать foreach) предположительно, вы используете .NET 3.5.
Я не думаю, что полностью понимаю вашу схему - например, что можно сказать о том, что комментарий с ThreadId = 4 на вашей диаграмме находится под первым элементом ThreadId = 3 вместо второго?
Не зная особых подробностей о том, что вам нужно, в целом я бы рассмотрел структуру данных для комментариев с:
- Идентификатор комментария:идентификатор этого объекта
- Сонная артерия:идентификатор корневого элемента для потока (чтобы вы могли легко извлекать все комментарии для потока)
- Родительский идентификатор:идентификатор родительского элемента для этого комментария или 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();
}
}