关系的深度

时间:2014-10-31 12:03:03

标签: c# lambda .net-4.5

我正在试图弄清楚如何获得与自身相关的实体关系的深度。这是一个基本评论项,可以有一个或多个链接到它的回复评论。

现在,对于这些回复的评论中的每一条,我想知道它们与顶级节点有多深。

即,我想知道下图中评论中的深度:

Comment levels

这是截至目前的代码,变量ResponseTo是此评论作为响应的关系,如果不是响应,则值为null

var comments = db.Comments
.Where(c => c.Post.ID == id && c.Status == Helpers.StatusCode.Visible)
.Select(x => new CommentTemp()
    {
        Id = x.ID,
        Text = x.Text,
        Avatar = "-1",
        Username = (x.User != null ? x.User.UserName : "Anonymous"),
        UserID = (x.User != null ? (int?) x.User.Id : null),
        ResponseTo = (x.ResponseTo == null ?  null : (int?) x.ResponseTo.ID),
        CommentDepth = ??? // <--- how do i select the depth of the response to relations?
        Created = x.Created
    })
.ToList();

我现在只能想到的选项是在创建评论时保存它,但如果可能的话,我希望能够即时获取它。

1 个答案:

答案 0 :(得分:1)

嗯,确实听起来你想在数据库中保存这些信息,除非真的有充分的理由不这样做。无论哪种方式,Linq都不是真正的递归友好。

您可以通过创建字典和扩展来获得深度以递归方式追踪它。

int GetDepth(Comment comment, 
                IDictionary<int, Comment> comments,  /*key=commentId, val=Comment*/
                IDictionary<int, int> depthMemoization, /* key=commentId, val=depth*/
                int currentDepth = 0)
{
    if(depthMemoization.ContainsKey(comment.Id))
        return depthMemoization[comment.Id];

    if(comment.ParentId==null)
        return currentDepth;

    var parentComment = comments[comment.ParentId.Value];

    int calculatedDepth = GetDepth(parentComment, comments, 
                            depthMemoization,
                            ++currentDepth);

    depthMemoization[comment.Id] = calculatedDepth ;

    return depth;
}