树结构查询
⚠️
该文档可能已过期。
- SelectMore:按树结构遍历,选择“树节点中 所有 满足条件的 节点”;
 - SelectUntil:按树结构遍历,直到 在每个子路径中找到满足条件的节点,选择 该节点;
 - SelectWhile:按树结构遍历,选择“所有子路径 中连续满足条件的 路径节点”。
 
例如,雇员(Employees)表按照 EmployeeID 和 ReportsTo 定义结构如下:

| EmployeeID | FirstName | ReportsTo | ReportsTo_ | 
|---|---|---|---|
| 1 | Nancy | 2 | Andrew | 
| 2 | Andrew | ||
| 3 | Janet | 2 | Andrew | 
| 4 | Margaret | 2 | Andrew | 
| 5 | Steven | 2 | Andrew | 
| 6 | Michael | 5 | Steven | 
| 7 | Robert | 5 | Steven | 
| 8 | Laura | 2 | Andrew | 
| 9 | Anne | 5 | Steven | 
SelectMore
按树结构遍历,选择“树节点中 所有 满足条件的 节点”。
例如,查询由 2 号雇员 Andrew 领导的所有成员(2, 1, 3, 4, 5, 6, 7, 9, 8):

方法: 使用 SelectMore 从根节点查找即可。
var employees = sqlite.Employees
    .Include(x => x.Superordinate)
    .Include(x => x.Subordinates)
    .ToArray();
var query = employees
    .Where(x => x.EmployeeID == 2)
    .SelectMore(x => x.Subordinates);
 
var result = query.Select(x => new
{
    x.EmployeeID,
    x.FirstName,
    x.ReportsTo,
    ReportsTo_ = x.Superordinate?.FirstName,
});运行结果:
| EmployeeID | FirstName | ReportsTo | ReportsTo_ | 
|---|---|---|---|
| 2 | Andrew | ||
| 1 | Nancy | 2 | Andrew | 
| 3 | Janet | 2 | Andrew | 
| 4 | Margaret | 2 | Andrew | 
| 5 | Steven | 2 | Andrew | 
| 6 | Michael | 5 | Steven | 
| 7 | Robert | 5 | Steven | 
| 9 | Anne | 5 | Steven | 
| 8 | Laura | 2 | Andrew | 
SelectUntil
按树结构遍历,直到 在每个子路径中找到满足条件的节点,选择 该节点。
例如,查询由 2 号雇员 Andrew 领导的所有基层员工(叶节点,1, 3, 6, 7, 9, 8):

方法:使用 SelectUntil 从根节点查找,直到节点 Subordinates 为空。
var employees = sqlite.Employees
    .Include(x => x.Superordinate)
    .Include(x => x.Subordinates)
    .ToArray();
var query = employees
    .Where(x => x.EmployeeID == 2)
    .SelectUntil(x => x.Subordinates, x => !x.Subordinates.Any());
 
var result = query.Select(x => new 
{
    x.EmployeeID,
    x.FirstName,
    x.ReportsTo,
    ReportsTo_ = x.Superordinate?.FirstName,
});运行结果:
| EmployeeID | FirstName | ReportsTo | ReportsTo_ | 
|---|---|---|---|
| 1 | Nancy | 2 | Andrew | 
| 3 | Janet | 2 | Andrew | 
| 4 | Margaret | 2 | Andrew | 
| 6 | Michael | 5 | Steven | 
| 7 | Robert | 5 | Steven | 
| 9 | Anne | 5 | Steven | 
| 8 | Laura | 2 | Andrew | 
SelectWhile
按树结构遍历,选择“所有子路径 中连续满足条件的 路径节点”。
例如,查询由 2 号雇员 Andrew 领导的所有非基层员工(非叶节点,2, 5):

方法:使用 SelectWhile 从根节点查找路径,直到节点 Subordinates 为空。
var employees = sqlite.Employees
    .Include(x => x.Superordinate)
    .Include(x => x.Subordinates)
    .ToArray();
var query = employees
    .Where(x => x.EmployeeID == 2)
    .SelectWhile(x => x.Subordinates, x => x.Subordinates.Any());
 
var result = query.Select(x => new 
{
    x.EmployeeID,
    x.FirstName,
    Subordinates = string.Join(", ", x.Subordinates
        .SelectMore(s => s.Subordinates)
        .Select(s => s.FirstName)),
});运行结果:
| EmployeeID | FirstName | Subordinates | 
|---|---|---|
| 2 | Andrew | Nancy, Janet, Margaret, Steven, Michael, Robert, Anne, Laura | 
| 5 | Steven | Michael, Robert, Anne |