EFCore中的CTE公用表表达式

问题描述

我的数据库中有一个表,用于存储位置的层次结构。它具有3列(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,经过几次搜索,我发现How does Entity Framework work with recursive hierarchies? Include() seems not to work with it How to do recursive load with Entity framework?以及一堆都是旧的。

我发现的所有解决方案要么对层次结构的深度进行了硬编码(使用Include),要么在C#中进行了递归。设置完成后,我的问题是,这样做的最佳解决方案是什么?

我可以使用FromsqlRaw (类似以下代码),但是我不喜欢用C#手动编写查询

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

我正在使用EFCore 3.1.7

解决方法

EF和EF Core有些功能是做不到的。

递归CTE是其中之一。

对不起,但是您只需要使用原始sql-您可以将其设为db函数或将sql放入C#代码中。两种方法都有优点和缺点:

  • 将其放入代码中可以更轻松地更改和跟踪您的代码 代码控制(可能是git吗?)
  • 将其作为函数放入数据库中 允许数据库更好地对其进行优化-尽管达到何种程度 需要SQL专家进行评论。

老实说,不要浪费时间尝试做一些无法完成的事情。

问候,

亚当。