EFCore中的CTE(公共表达式)

9

我在数据库中有一张存储位置层级结构的表格。它有三列(Id, Name, ParentId)。我需要根据某个条件加载一些行和它们所有的父项直到根节点。如果是在ADO中,我会使用以下语句。

with Temp
as
(
    select * from Locations where Name like '%filter%'

    union all

    select Locations.* 
    from Temp join Locations on Temp.ParentId = Locations.Id
)
select * from Temp

我正在使用EFCore,通过几次搜索,我找到了《实体框架如何处理递归层次结构?Include()似乎无法处理》《如何在实体框架中进行递归加载?》以及一大堆其他的解决方案,它们都已经很老了。

我所找到的所有解决方案,要么硬编码层次深度(使用Include),要么在C#中进行递归。总之,我的问题是:什么是最好的解决方案呢?

我可以使用FromSqlRaw(类似下面的代码),但我不喜欢在C#中手动编写查询语句。

    var locations = DataContext.Locations
    .FromSqlRaw("MyQuery").ToList();

我正在使用EFCore 3.1.7


使用 Oracle,您可以选择深度优先/广度优先——不确定 SQL Server 是否有相似的功能。因此,也许这个链接会有所帮助:https://stackoverflow.com/questions/11636420/a-real-recursion-with-cte/11637387#11637387 - JGFMK
谢谢您的评论@JGFMK,但是这个链接是SQL的答案,而不是EFCore的答案。我已经在我的问题中提供了它。 - Hamid Mayeli
1
如果您不喜欢嵌入原始查询文本,您可以编写视图、存储过程或表值函数来返回数据,并访问它们。我没有直接使用过EF Core,但如果它支持递归查询,我会感到惊讶。 - Jeroen Mostert
感谢@JeroenMostert, 由于我正在使用Code First,所以我应该编写原始查询来创建SP或View。因此,这不是我要寻找的内容。 - Hamid Mayeli
1个回答

7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接