让所有员工都在经理C#下

时间:2015-06-18 17:25:26

标签: c# sql .net recursion

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

员工包括:

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;
}

非常感谢所有帮助!

3 个答案:

答案 0 :(得分:1)

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

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;
}

你可以采取更多的高性能方法,但为了简单起见,如果你只想在树上进行递归,这就可以了。您可能希望为数据问题添加一些检查,例如确保没有无限递归(如果两个员工设法相互报告......这听起来很奇怪,但大公司会发生奇怪的事情)。

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

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

脱离我的头脑(我没有经过性能测试)这就是我在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