我对SQL和实体框架(ADO.NET实体映射)中的 递归 都是陌生的。我正在进行评论管理,其中有一个Comments表,并且该表包含列NewsID, CommentID, ParentCommentID, IndentLevel, CreatedTime。
Comments
NewsID, CommentID, ParentCommentID, IndentLevel, CreatedTime
我正在尝试获取特定新闻项目的评论列表,其中所有评论均根据父项和创建时间下的子项进行排列,如下所示:
CommentID | time | ParentCommentID Guid1 | t1 | null Guid4 | t4 | Guid1 Guid2 | t2 | null Guid3 | t3 | Guid2
必须优先考虑子级父母关系,然后是创建的时间。
到目前为止,我所依靠的是(来自互联网资源和以前的stackoverflow Q / A)
SQL:
WITH cte_name ( column_name [,...n] ) AS ( CTE_query_definition –- Anchor member is defined. UNION ALL CTE_query_definition –- Recursive member is defined referencing cte_name. ) -- Statement using the CTE SELECT * FROM cte_name
为此,我参考了我有这个主意的链接:https : //stackoverflow.com/a/6225373/892788
但是我试图理解代码却徒劳。有人可以给我关于在Entity Framework中编写递归CTE的更好详细的解释吗?
private IEnumerable<NewsComment> ArrangeComments(IEnumerable<NewsComment> commentsList, string parentNewsComntID, int level) { Guid parentNewsCommentID; if (parentNewsComntID != null) { parentNewsCommentID = new Guid(parentNewsComntID); } else parentNewsCommentID = Guid.Empty; return commentsList.Where(x => x.ParentCommentID == parentNewsCommentID).SelectMany(x => new[] { x }.Concat(ArrangeComments(commentsList, x.NewsCommentID.ToString(), level + 1)); }
我在方法内部使用以下方法:
return ArrangeComments(commentList,null , 0);
我已经尝试过了,但似乎一无所获。尽管有关于SQL递归的解释,但是Linq的示例较少,并且由于不那么熟悉,对我来说也很模糊。有人可以帮我理解Linq中的CTE递归很棒吗
提前致谢
AFAIK在LINQ和EF中均不支持递归CTE。解决方案是将CTE作为视图公开。有关使用EF Code First和Migrations进行递归或分层查询的文章,介绍了如何使用EF Code First迁移来部署这种视图。
尝试通过进行递归客户端迭代来模拟CTE并不能扩展到大型数据集,并导致与服务器之间的交流。请注意,您的EF代码是如何IEnumerable不返回的IQueryable,这意味着它将实现每个级别,然后将每个条目的下一个级别串联 为一个单独的请求 。基于LINQ的解决方案将适用于条目数有限的浅层次结构(并且请注意,许多项目 可以 具有这种数据布局,用户帖子/答案是典型示例),但是在具有许多元素的深层次结构中会崩溃。
IEnumerable
IQueryable