using System.Collections.Generic;
public class ReportingLineList
public int UserId { get; set; }
public int? SupervisorUserId { get; set; }
public static void Main()
List<ReportingLineList> employeeList = new()
new() { UserId = 1, SupervisorUserId = 10 },
new() { UserId = 2, SupervisorUserId = 1 },
new() { UserId = 3, SupervisorUserId = 1 },
new() { UserId = 4, SupervisorUserId = 3 },
new() { UserId = 5, SupervisorUserId = 10 },
new() { UserId = 6, SupervisorUserId = 5 },
new() { UserId = 7, SupervisorUserId = 6 },
new() { UserId = 8, SupervisorUserId = 6 },
new() { UserId = 9, SupervisorUserId = 8 }
var employeesWithReportingLevel = employeeList
UserId = employee.UserId,
ReportingLevel = GetReportingLevel(employeeList, employee.UserId)
.OrderBy(reportingEmployee => reportingEmployee.ReportingLevel)
Console.WriteLine($"GetReportingLevel() was called {_getReportingLevelCallCount} times");
Console.WriteLine("UserId | ReportingLevel");
Console.WriteLine("-------|----------------");
foreach (var employee in employeesWithReportingLevel)
Console.WriteLine($"{employee.UserId.ToString().PadLeft(6, ' ').PadRight(6, ' ')} | {employee.ReportingLevel}");
private static int _getReportingLevelCallCount;
private static int GetReportingLevel(IEnumerable<ReportingLineList> employeeList, int userId)
_getReportingLevelCallCount++;
var subordinates = employeeList
.Where(emp => emp.SupervisorUserId == userId);
return 1 + subordinates.Max(sub => GetReportingLevel(employeeList, sub.UserId));