LinqToSQL递归选择

时间:2018-07-24 09:19:22

标签: c# sql linq linq-to-sql

在您将其标记为重复之前,我进行了广泛的搜索,但没有提供我的答案。我看过了 Recursive select via LINQ?linq to sql recursive queryhttp://www.scip.be/index.php?Page=ArticlesNET18#AsHierarchy

我需要的是第二和第三链接上的反向链接。但是我不知道该怎么做。

看这个例子:

EmployeeId  Name  ManagerId
----------------------------
    1        A     null
    2        B     1
    3        C     1
    4        D     3
    5        E     2
    6        F     5

我需要的是,如果登录 A A 将需要递归查看他/她的所有下属。在这种情况下, A 将看到所有人的详细信息。

所以:

  1. 如果 B 登录,则他/她应该看到: E F 和他/她自己( B
  2. 如果 C 登录,则他/她应该看到: D 和他/她的自己( C
  3. 如果 D 登录,那么他/她应该看到:他/她的自己( D
  4. 如果 E 登录,则他/她应该看到: F 和他/她的自己( E
  5. 如果 F 登录,则他/她应该看到:他/她的自己( F

我的问题是,如何创建递归的linqtosql?

我当前的解决方案是将所有员工记录读取到列表中,然后进行递归检查。如果我有很多员工,将所有记录加载到列表中似乎浪费资源。

有什么主意吗?

欢呼

1 个答案:

答案 0 :(得分:0)

最好的解决方案可能是在Sql中做到这一点。

如果无法修改Sql数据库,则可以使用ExecuteQuery直接执行Sql cte,例如

int employeeId = 1;

var query = this.ExecuteQuery<Employee>(
@" 
; WITH cte 
As
(   
    SELECT Employee.* FROM  Employee   WHERE EmployeeId = {0}

    UNION All SELECT so.* FROM Employee so INNER JOIN cte ON cte.EmployeeID = so.ManagerId
)

SELECT * FROM cte
", new object[] { employeeId } ); 

显然,您需要对此进行测试。

请注意,如果您执行类似query.Select(a=> new { a.EmployeeID, a.Name})的操作,则此操作仍会在后台执行select *,其他列将下载到客户端,然后忽略,但是您可以创建一个包含以下字段的类您想要并更改cte以仅返回这些列。