C# 使用ef core获取父子表的递归rootID
我有一个SQL表,它的构建类似于树列表(父-子)。意味着你有rootId和childId。每个实体都有一个ParentId。如果ParentId为null,则该元素是根项 这里是分层体系结构的一个示例C# 使用ef core获取父子表的递归rootID,c#,entity-framework,linq,.net-core,entity-framework-core,C#,Entity Framework,Linq,.net Core,Entity Framework Core,我有一个SQL表,它的构建类似于树列表(父-子)。意味着你有rootId和childId。每个实体都有一个ParentId。如果ParentId为null,则该元素是根项 这里是分层体系结构的一个示例 - Fruit (1) - TreeFruits (2) - Apple (4) - Bulb (5) - SeaFruits (3) - DeepSeaFruits (6) - Sushi (9) - Kraken (13) - S
- Fruit (1)
- TreeFruits (2)
- Apple (4)
- Bulb (5)
- SeaFruits (3)
- DeepSeaFruits (6)
- Sushi (9)
- Kraken (13)
- Shrimp (7)
- Fish (8)
- Vegetable (10)
- Carrot (11)
- Potato (12)
您可以看到每个根元素(数字1和10)至少有一个子元素。但元素的深度还不清楚
下面是一个表格的示例
------------
| Id* |<---
| | |
| ParentId |----
| Name |
------------
------------
|Id*|如果您不想从数据库加载所有记录,然后对其进行处理,则有两种选择:
解决方案1:在数据库中编写存储过程和处理
解决方案2:编写一个递归函数,向数据库发送多个请求(以根深度为单位)
下面是解决方案2的一个函数:
public async Task<int> GetRoot(int id)
{
var current = await _dbContext.Set<Entity>().Where(p => p.Id == id).FirstOrDefaultAsync();
if (current.ParentId is not null)
{
return await GetRoot(current.ParentId.Value);
}
else
{
return current.Id;
}
}
公共异步任务GetRoot(int-id)
{
var current=await_dbContext.Set(),其中(p=>p.Id==Id.FirstOrDefaultAsync();
if(current.ParentId不为null)
{
return wait GetRoot(current.ParentId.Value);
}
其他的
{
返回当前.Id;
}
}
这是递归CTE,EF不支持。您知道是否可以通过linq查询调用此CTE,以及是否可以模拟此CTE进行单元测试。我在linq查询中找到了如何调用CTE的方法。现在最后一个问题是,如何为单元测试模拟它。调用CTE可以使用“DbFunction”-属性,但我不知道如何为单元测试创建模拟(请参阅)。