【问题标题】:LinqToSQL recursive selectLinqToSQL 递归选择
【发布时间】:2018-12-31 20:38:24
【问题描述】:

在您将其标记为重复之前,我进行了广泛的搜索,但没有提供我的答案。我已经看过了 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登录,那么他/她应该看到:EF和他/她自己(B强>)
  2. 如果C登录,那么他/她应该看到:D和他/她自己(C
  3. 如果 D 登录,那么他/她应该看到:他/她自己 (D)
  4. 如果E登录,那么他/她应该看到:F和他/她自己(E
  5. 如果F登录,那么他/她应该看到:他/她自己(F

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

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

有什么想法吗?

干杯

【问题讨论】:

  • 根据员工数量,如果您编写查询以仅返回所需的数据量(例如仅显示的三列) - 您可能会发现将所有数据读入更有效内存并在该数据上运行递归方法。否则,您会发现在每个递归级别,每个托管员工都需要一个 SQL 查询——多个小查询的开销可能超过单个大查询的开销。例如,如果您有一名高级经理(managerID != null)监督 10 名经理,每名经理监督 5 名员工 - 这将需要 61 次查询。
  • 您好,Paul,它适用于中型组织。它大约有数百名员工。会有很多操作(审批费用、奖金、kpi等...)。我只是试图让它尽可能高效(如果可能的话)。现在,我正在加载所有列表并通过递归函数对其进行过滤。只是好奇是否有办法做到这一点。如果没有,我会忍受将所有记录加载到列表中。
  • 如果只有几百名员工,那么获取所有数据的单个查询听起来不会有太大改进,而且可能会变得更糟。改进事情的最佳方法是使用存储过程并让数据库服务器完成工作 - 这样您就有一个查询并且只返回所需的数据。
  • 必须是递归的吗?如果您知道最大级别数,则可以执行 Employees.Where(r=> r.EmployeeId == id || r.Manager.EmployeeId == id || r.Manager.Manager.EmployeeId == id || r.Manager.Manager.Manager.EmployeeId == id ... ) 之类的操作
  • 您能否介绍一下您希望答案在什么数据结构中?

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


【解决方案1】:

最好的解决方案可能是在 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=&gt; new { a.EmployeeID, a.Name}) 之类的操作,那么这仍会在后台执行 select * 并且其他列将被下载到客户端然后被忽略,但您可以创建一个包含所需字段的类并更改 cte 以仅返回这些列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 2023-03-29
    • 2012-09-20
    相关资源
    最近更新 更多