asp.net врезал комментарии?

Я работаю над созданием блога в ASP.net 4.0 и SQL Server 2008 и хотел бы узнать, как создать систему многопоточных комментариев. Под резьбой я подразумеваю, что у каждого комментария будет ссылка для ответа, а комментарии имеют отступ под комментарием, на который он является ответом. Таким образом, вы можете либо ответить на саму статью, либо ответить на любой из комментариев.

Это очень часто встречается на форумах и блогах, но я не могу найти ни одной статьи, которая бы объясняла и показывала пример кода о том, как это делается.

Вот то, что я создал, но он работает только на одном уровне глубины. Я хотел бы сделать его рекурсивным, чтобы не было ограничений по уровню глубины. Как я могу это сделать? Любые советы, статьи с примерами кода были бы потрясающими!

Комментарии дБ Таблица

commentId
parentId
postId
date
author
authorEmail
authorURL
authorIP
content
IsApproved

Разметка ASP.NET:

<asp:ListView ID="ListView1" runat="server" onitemdatabound="ListView1_ItemDataBound">
<ItemTemplate>
    <div class="commentwrap">
        <div class="commentsTitleArea">
            <span class="commentCounter"><%# Convert.ToInt32(Container.DisplayIndex) + 1%>. </span>&nbsp;&nbsp;<img src="../images/decoy-icon-16px.png" alt="Comment by..." title="Comment by..." class="blogCommentIcon" /><a href='<%# Eval("AuthorUrl")%>' target="_blank" rel="nofollow"><%# " " + Eval("Author")%></a>&nbsp;&nbsp;<%# Eval("Date")%></div>
        <div class="commentText">
            <%# Eval("Content") %>
            <div><span class="btnCommentReply"><a href='<%# "article.aspx?article=" + Request.QueryString["article"] + "&amp;cid=" + Eval("commentId") + "#comment" %>'>REPLY</a></span></div>
        </div>
        <asp:ListView ID="ListView2" runat="server">
            <ItemTemplate>
                <div class="commentwrap commentNest">
                    <div class="commentsTitleArea">
                        <span class="commentCounter"><%# Convert.ToInt32(Container.DisplayIndex) + 1%>. </span>&nbsp;&nbsp;<img src="../images/decoy-icon-16px.png" alt="Comment by..." title="Comment by..." class="blogCommentIcon" /><a href='<%# Eval("AuthorUrl")%>' target="_blank" rel="nofollow"><%# " " + Eval("Author")%></a>&nbsp;&nbsp;<%# Eval("Date")%></div>
                    <div class="commentText">
                        <%# Eval("Content") %>
                    </div>
                </div>
            </ItemTemplate>
            <EmptyDataTemplate>
            </EmptyDataTemplate>
            <LayoutTemplate>
                <div id="itemPlaceholderContainer" runat="server">
                    <span id="itemPlaceholder" runat="server" />
                </div>
            </LayoutTemplate>
        </asp:ListView>
    </div>
</ItemTemplate>
<EmptyDataTemplate>
</EmptyDataTemplate>
<LayoutTemplate>
    <div id="itemPlaceholderContainer" runat="server">
        <span id="itemPlaceholder" runat="server" />
    </div>
    <div class="dataPagerWrap">
        <asp:DataPager ID="ListViewpager" runat="server" PagedControlID="ListView1" PageSize="30" QueryStringField="page">
            <Fields>
                <asp:NextPreviousPagerField ShowFirstPageButton="True" ShowNextPageButton="False" ShowPreviousPageButton="False" FirstPageText="«" ButtonCssClass="dataPagerBackForward" />
                <asp:NumericPagerField ButtonCount="8" CurrentPageLabelCssClass="dataPagerCurrent" NumericButtonCssClass="dataPager" PreviousPageText="..." NextPageText="..." NextPreviousButtonCssClass="dataPagerBackForward" />
                <asp:NextPreviousPagerField ShowLastPageButton="True" ShowNextPageButton="False" ShowPreviousPageButton="False" LastPageText="»" ButtonCssClass="dataPagerBackForward" />
            </Fields>
        </asp:DataPager>
    </div>
    <div class="padding"></div>
</LayoutTemplate>


    ALTER PROCEDURE [dbo].[sp_blog_GetComments]
(
    @article int
)
AS
    SET NOCOUNT ON;

    SELECT 
    post_Comments.Author, 
    post_Comments.AuthorEmail, 
    post_Comments.AuthorUrl, 
    post_Comments.Content, 
    post_Comments.Date, 
    post_Comments.commentId 
    FROM post_Comments 
    INNER JOIN 
    posts 
    ON post_Comments.postId = posts.postId 
    WHERE(post_Comments.postId = @article) 
    AND (post_Comments.IsApproved = 1) 
    AND (post_Comments.ParentId IS NULL) 
    AND (posts.IsPublished = 1) 
    AND (posts.PublishOnDate <= GETDATE())

    SELECT 
    Author, 
    AuthorEmail, 
    AuthorUrl, 
    Content, 
    Date, 
    ParentId
    FROM post_Comments
    WHERE (postId = @article) 
    AND (IsApproved = 1)

Хранимая процедура:

ALTER PROCEDURE [dbo].[Sp_blog_getcomments] (@article INT)
AS
    SET nocount ON;

    SELECT post_comments.author,
           post_comments.authoremail,
           post_comments.authorurl,
           post_comments.content,
           post_comments.date,
           post_comments.commentid
    FROM   post_comments
           INNER JOIN posts
                   ON post_comments.postid = posts.postid
    WHERE ( post_comments.postid = @article )
          AND ( post_comments.isapproved = 1 )
          AND ( post_comments.parentid IS NULL )
          AND ( posts.ispublished = 1 )
          AND ( posts.publishondate <= Getdate() )

    SELECT author,
           authoremail,
           authorurl,
           content,
           date,
           parentid
    FROM   post_comments
    WHERE  ( postid = @article )
           AND ( isapproved = 1 ) 

1 ответ

Решение

Один подход, который я помню где-то, заключался в том, чтобы вместо использования идентификатора комментария и идентификатора родителя комментарии имели идентификатор комментария и "ключ сортировки", который представлял собой объединение всех идентификаторов комментариев их предков.

Например, если на комментарий 1 было два ответа, комментарии 2 и 3, ключи сортировки были бы:

1 : 0001
2 : 0001.0002
3 : 0001.0003

Тогда, если кто-то ответил на комментарий 2, это было бы..

4 : 0001.0002.0004

Поэтому, если вы выберете все комментарии и отсортируете по этому ключу сортировки, они будут выпадать в правильном порядке.

Затем, чтобы сделать отступ, вы просто смотрите на длину ключа сортировки, чтобы увидеть, насколько глубокий уровень комментария, и сделаете отступ в соответствующем количестве.

Добавить комментарии легко: ключ сортировки нового комментария - это просто ключ сортировки родителя, в конце которого добавляется его собственный идентификатор.

Другие вопросы по тегам