内存查询
树查询

树结构查询

⚠️

该文档可能已过期。

  • SelectMore:按树结构遍历,选择“树节点中 所有 满足条件的 节点”;
  • SelectUntil:按树结构遍历,直到 在每个子路径中找到满足条件的节点,选择 该节点
  • SelectWhile:按树结构遍历,选择“所有子路径 中连续满足条件的 路径节点”。

例如,雇员(Employees)表按照 EmployeeIDReportsTo 定义结构如下:

employee-tree.png

EmployeeIDFirstNameReportsToReportsTo_
1Nancy2Andrew
2Andrew
3Janet2Andrew
4Margaret2Andrew
5Steven2Andrew
6Michael5Steven
7Robert5Steven
8Laura2Andrew
9Anne5Steven

SelectMore

按树结构遍历,选择“树节点中 所有 满足条件的 节点”。

例如,查询由 2 号雇员 Andrew 领导的所有成员(2, 1, 3, 4, 5, 6, 7, 9, 8):

select-more.png

方法: 使用 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,
});

运行结果:

EmployeeIDFirstNameReportsToReportsTo_
2Andrew
1Nancy2Andrew
3Janet2Andrew
4Margaret2Andrew
5Steven2Andrew
6Michael5Steven
7Robert5Steven
9Anne5Steven
8Laura2Andrew

SelectUntil

按树结构遍历,直到 在每个子路径中找到满足条件的节点,选择 该节点

例如,查询由 2 号雇员 Andrew 领导的所有基层员工(叶节点,1, 3, 6, 7, 9, 8):

select-until.png

方法:使用 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,
});

运行结果:

EmployeeIDFirstNameReportsToReportsTo_
1Nancy2Andrew
3Janet2Andrew
4Margaret2Andrew
6Michael5Steven
7Robert5Steven
9Anne5Steven
8Laura2Andrew

SelectWhile

按树结构遍历,选择“所有子路径 中连续满足条件的 路径节点”。

例如,查询由 2 号雇员 Andrew 领导的所有非基层员工(非叶节点,2, 5):

select-while.png

方法:使用 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)),
});

运行结果:

EmployeeIDFirstNameSubordinates
2AndrewNancy, Janet, Margaret, Steven, Michael, Robert, Anne, Laura
5StevenMichael, Robert, Anne