从 EF 核心递归选择特定任务及其 ChildTasks
Selecting a specific Task and its ChildTasks recursively from EF core
我有一个 TaskItem class,它有相同类型的子项:
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; }
}
以平面列表的形式递归获取任务及其子任务:
var taskList = taskDBContext.TaskItems.Include(c => c.ChildTasks)
.Where(x => x.Id == taskId)
.SelectMany(x => x.ChildTasks)
.ToList();
问题是我总是得到一个任务,尽管这个任务有许多不同级别的孙子。我的方案是将特定父项及其子项和孙项加载为单个列表。
此外,请告诉我这是一个好的设计还是我必须更改它。
EF Core 不会以递归方式为您获取数据,您需要自己为每个级别获取数据:
var secondLevelx = taskDBContext.TaskItems
.Where(x => x.Id == taskId)
.SelectMany(x => x.ChildTasks)
.SelectMany(x => x.ChildTasks)
.ToList();
或:
var secondLevelx = taskDBContext.TaskItems
.Where(x => taskList.Select(t=>t.Id).Contains(x.Id))
.SelectMany(x => x.ChildTasks)
.ToList();
并在有结果时重复。
或者如果您的数据库支持,则编写递归 sql 查询(例如,对于 SQL 服务器,您可以使用 CTE's)。
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());
我有一个 TaskItem class,它有相同类型的子项:
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; }
}
以平面列表的形式递归获取任务及其子任务:
var taskList = taskDBContext.TaskItems.Include(c => c.ChildTasks)
.Where(x => x.Id == taskId)
.SelectMany(x => x.ChildTasks)
.ToList();
问题是我总是得到一个任务,尽管这个任务有许多不同级别的孙子。我的方案是将特定父项及其子项和孙项加载为单个列表。
此外,请告诉我这是一个好的设计还是我必须更改它。
EF Core 不会以递归方式为您获取数据,您需要自己为每个级别获取数据:
var secondLevelx = taskDBContext.TaskItems
.Where(x => x.Id == taskId)
.SelectMany(x => x.ChildTasks)
.SelectMany(x => x.ChildTasks)
.ToList();
或:
var secondLevelx = taskDBContext.TaskItems
.Where(x => taskList.Select(t=>t.Id).Contains(x.Id))
.SelectMany(x => x.ChildTasks)
.ToList();
并在有结果时重复。
或者如果您的数据库支持,则编写递归 sql 查询(例如,对于 SQL 服务器,您可以使用 CTE's)。
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());