C# 从EF core递归选择特定任务及其子任务

C# 从EF core递归选择特定任务及其子任务,c#,linq,ef-core-3.1,C#,Linq,Ef Core 3.1,我有一个TaskItem类,它具有相同类型的子项: public class TaskItem { public Guid Id { get;set; } // Parent Task public TaskItem ParentTask { get; set; } public Guid? ParentTaskId { get; set; } //Child Tasks public ICollection<TaskItem >

我有一个TaskItem类,它具有相同类型的子项:

public class TaskItem
{
    public Guid Id { get;set; }

    // Parent Task

    public TaskItem ParentTask { get; set; }

    public Guid? ParentTaskId { get; set; }

   //Child Tasks

    public ICollection<TaskItem > ChildTasks{ get; set; }
}
问题是,我总是得到一项任务,尽管该任务有多个不同级别的孙子。我的场景是将特定的父母及其子女和孙子作为单个列表加载


另外,请告诉我这是否是一个好的设计,或者我是否必须更改它。

EF Core不会递归地为您获取数据,您需要自己为每个级别执行此操作:

var secondLevelx = taskDBContext.TaskItems
    .Where(x => x.Id == taskId)
    .SelectMany(x => x.ChildTasks)
    .SelectMany(x => x.ChildTasks)
    .ToList();
或:

并在有结果时重复

或者,如果您的数据库支持递归sql查询,则编写它(例如,您可以使用sql Server)

UPD

如果您可以按级别提出请求(也可以认为您可以向查询传递的参数数量是有限的),并且没有周期,则可以执行以下操作:

var taskList = new List<TaskItem>();
var toQuery = new List<Guid> {taskId};

do
{
    var current = taskDBContext.TaskItems
        .Where(x => toQuery.Contains(x.Id))
        .SelectMany(x => x.ChildTasks)
        .ToList();
    taskList.AddRange(current);
    toQuery = current.Select(x => x.Id).ToList();
} while (toQuery.Any());
var taskList=新列表();
var toQuery=新列表{taskId};
做
{
var current=taskDBContext.TaskItems
.Where(x=>toQuery.Contains(x.Id))
.SelectMany(x=>x.ChildTasks)
.ToList();
taskList.AddRange(当前);
toQuery=current.Select(x=>x.Id).ToList();
}while(toQuery.Any());

这是否回答了您的问题@JohnathanBarclay不,我正在尝试将特定的父项及其子项和孙子项加载到它们当前的级别。找到了一种递归获取项的方法:找到了一种递归获取项的方法:@John是的,它基本上以递归的方式完成了我在这里写的内容,你也可以使用简单的while循环来完成。但它仍然会对每个级别提出一个请求。您能用该解决方案更新您的答案吗?
var secondLevelx = taskDBContext.TaskItems
    .Where(x => taskList.Select(t=>t.Id).Contains(x.Id))
    .SelectMany(x => x.ChildTasks)
    .ToList();  
var taskList = new List<TaskItem>();
var toQuery = new List<Guid> {taskId};

do
{
    var current = taskDBContext.TaskItems
        .Where(x => toQuery.Contains(x.Id))
        .SelectMany(x => x.ChildTasks)
        .ToList();
    taskList.AddRange(current);
    toQuery = current.Select(x => x.Id).ToList();
} while (toQuery.Any());