我正在试图弄清楚如何获得与自身相关的实体关系的深度。这是一个基本评论项,可以有一个或多个链接到它的回复评论。
现在,对于这些回复的评论中的每一条,我想知道它们与顶级节点有多深。
即,我想知道下图中评论中的深度:
这是截至目前的代码,变量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();
我现在只能想到的选项是在创建评论时保存它,但如果可能的话,我希望能够即时获取它。
答案 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;
}