我对SQL和实体框架(ADO.NET实体Map)中的递归都是新手。我正在处理一个注解管理,其中我有一个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 Server中创建一个存储过程,并使用函数导入调用它来完成。另一件事是在实体框架中使用Linq。
- 在SQL Server中,它以以下格式使用
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
- 但是在尝试这个之前,我想试试Linq。
为此,我有参考这个链接,我有这个想法:https://stackoverflow.com/a/6225373/892788
但是我已经试着去理解代码,但是徒劳。有没有人能给我一个更好更详细的解释关于在实体框架中编写递归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递归吗?这很好
先谢了
3条答案
按热度按时间6uxekuva1#
AFAIK,截至2022年中期,LINQ和EF仍然不支持递归CTE。解决方案是将CTE公开为视图。关于Recursive or hierarchical queries using EF Code First and Migrations的文章介绍了如何使用EF代码优先迁移部署这样的视图。
尝试通过执行递归客户端迭代来模拟CTE并不能扩展到大型数据集,而且会导致与服务器之间的交流过于繁琐。这意味着它具体化每一层,然后将每个条目 * 的下一层连接为单独的请求 *。基于LINQ的解决方案将合理地用于具有有限条目计数的浅层次结构(并且注意,许多项目 * 可以 * 具有这样的数据布局,用户帖子/回答是典型的示例),但是在具有许多元素的深层次结构下将崩溃。
093gszye2#
把CTE查询放到StoredProcedure中,然后从Code中调用它。EF提供了所有的方法(调用SP和检索结果)。我自己也做了同样的事情,效果很好。
无法使用Linq写入CTE查询Common Table Expression (CTE) in linq-to-sql?
示例ArrangeComments是一个递归过程,它调用自己,但我敢质疑它的性能。它从数据库中提取记录,然后在内存中应用操作。
new9mtju3#
在花了几个小时阅读这个问题后,我决定用C#来做,而不必创建数据库视图。
**注意:**此选项仅用于非性能关键型操作。http://nosalan.blogspot.se/2012/09/hierarchical-data-and-entity-framework-4.html的1000节点性能示例。
编码: