【问题标题】:Getting all Employees under a Manager C#将所有员工置于经理 C# 之下
【发布时间】:2015-09-04 11:26:00
【问题描述】:

我正在尝试在表格中列出经理下的所有员工。因此,经理可以访问网页并查看他/她下的每个人,包括所有层次结构。

员工由以下组成:

public class Employee
{
     int id {get; set;}
     string FirstName {get; set;}
     string LastName {get; set;}
     int EmployeeNumber {get; set;}
     int ManagerEmployeeNumber {get; set;}
}

目前,我只是获得经理的直接下属,但我想向经理下的每个人展示。

例子:

(FirstName: "Aaron", EmployeeNumber: 1, ManagerEmployeeNo: NULL)
(FirstName: "Jack", EmployeeNumber: 2, ManagerEmployeeNo: 1)
(FirstName: "Roger", EmployeeNumber: 3, ManagerEmployeeNo: 1)
(FirstName: "Nat", EmployeeNumber: 4, ManagerEmployeeNo: 2)
(FirstName: "Fred", EmployeeNumber: 4, ManagerEmployeeNo: 4)

这只是一个例子,经理们可以比这更深入。

这是我目前拥有的:

public List<Employee> GetManagedEmployees(Employee manager)
{
    var managedEmployees =_employeeDb.Employees.Where(e => e.ManagerEmployeeNumber == manager.EmployeeNumber).ToList();

    return managedEmployees.Any() == false ? null : managedEmployees;
}

非常感谢所有帮助!

【问题讨论】:

  • 这是学校的家庭作业吗?
  • @SQLPolice 不,不是
  • 您是在问如何使用SQLLINQ 执行此操作?
  • @RickS 他们都很好。我更喜欢 LINQ,但我也不介意使用存储过程来加载数据。

标签: c# sql .net recursion


【解决方案1】:

SQL 数据库并不特别擅长表示层次结构(尽管有些提供专有扩展,例如 Oracle Hierarchial Query)。

您将需要递归加载层次结构的每个级别。首先像现在一样获取即时报告。对于每个即时报告,您都需要加载他们的报告,依此类推,直到没有人有其他报告。

您当前的代码结构是一个很好的起点。您将为每个下属递归调用 GetManagedEmployees(),并将该调用的结果合并到直接和间接报告列表中,供生成报告的经理使用。

【讨论】:

    【解决方案2】:

    如果您只想要一个平面列表,那么这是简单的递归。在伪代码中,它看起来像这样:

    IList<Employee> GetEmployees(Employee manager)
    {
        var result = new List<Employee>();
    
        var employees = _employeeDb.Employees
                                   .Where(e => e.ManagerEmployeeNumber == manager.EmployeeNumber)
                                   .ToList();
    
        foreach (var employee in employees)
        {
            result.Add(employee);
            result.AddRange(GetEmployees(employee));
        }
    
        return result;
    }
    

    您当然可以采用更多高性能 方法,但为简单起见,如果您只想在树上递归,这可以解决问题。您可能需要对数据问题添加一些检查,例如确保没有无限递归(如果两名员工设法相互报告……这听起来很奇怪,但在大公司中会发生奇怪的事情)。

    如果你真的想要一些高性能的东西,你可以直接在 SQL 中使用Common Table Expressions 进行递归。自从我使用它已经有一段时间了,所以我没有一个方便的例子。但这是现代 SQL Server 实例的一个非常简洁的特性,确实允许在查询中进行递归。

    【讨论】:

    • .ToList()不用,不用的话应该会更快。
    • @EBrown 如果要返回 IList,则需要这样做
    • @EBrown:真的会有所作为吗?无论如何,该集合正在下一个代码块中实现。性能影响在于对数据库的递归调用,而不是在集合实现时。
    • @Blam 他实际上并没有返回那个查询,所以没有必要。他在foreach 中列举了它,但只是将每个员工添加到result 列表中。
    • @David 这只是一个建议,如果您要使用 LINQ,则不需要使用 .ToList()。它是多余的,如果集合变得庞大,它将开始对性能产生影响,因为您枚举相同的值两次。你没有去改变它,这是你的代码。只是提供一个有助于提高可读性和性能的建议。
    【解决方案3】:

    没想到(我还没有测试过性能)这就是我在 SQL SERVER 2008 或 2012 中的做法。

        DECLARE @allReports TABLE (employeeId int, managerEmployeeId int null);
    --Insert all the top-level managers first.
    INSERT INTO @allReports(employeeId,employeeManagerId)
    SELECT employeeNumber,managerEmployeeNumber from employees where managerEmployeeNumber is null;
    
    WHILE EXISTS (SELECT EmployeeNumber,ManagerEmployeeNumber  from employees where ManagerEmployeeNumber IS IN (SELECT employeeNumber from @allReports);
    BEGIN
    Insert into @allReports(employeeId,employeeManagerId)
    select e.employeeNumber, e.EmployeeManagerNumber from  employees e inner join @allReports a on e.EmployeeManagerNumber =a.employeeNumber 
    where e.managerEmployeeNumber IS NOT NULL
    END
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-28
      • 2021-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多