C# 检查经理列表是否在其任何经理中包含员工';s';他也是经理

C# 检查经理列表是否在其任何经理中包含员工';s';他也是经理,c#,list,recursion,C#,List,Recursion,我得到的SOAP响应如下所示: <Record> <EmployeeId>1</EmployeeId> <ManagerId>5</ManagerId> </Record> <Record> <EmployeeId>9</EmployeeId> <ManagerId>7</ManagerId> </Record> 1.

我得到的SOAP响应如下所示:

<Record>
    <EmployeeId>1</EmployeeId>
    <ManagerId>5</ManagerId>
</Record>
<Record>
    <EmployeeId>9</EmployeeId>
    <ManagerId>7</ManagerId>
</Record>

1.
5.
9
7.
我创建了一个具有以下属性的管理器类:

class Manager
    {
        public int Id { get; set; }
        public List<int> Employees { get; set; }
    }
类管理器
{
公共int Id{get;set;}
公共列表雇员{get;set;}
}
我循环浏览响应中的记录,用它填充经理列表:

List<Manager> managers = new List<Manager>();

foreach (Record record in records)
{
    Manager manager = managers.Find(m => m.Id == ManagerId);

    if (manager == null)
    {
            manager = new Manager
            {
                Id = ManagerId,
                Employees = new List<int>
                {
                    EmployeeId
                },
            };
            managers.Add(manager);
    }

    else
    {
        if (!manager.Employees.Contains(EmployeeId))
            {
                manager.Employees.Add(EmployeeId);
            }
    }
}
列表管理器=新列表();
foreach(记录中的记录)
{
Manager=managers.Find(m=>m.Id==ManagerId);
if(manager==null)
{
经理=新经理
{
Id=ManagerId,
雇员=新名单
{
雇员ID
},
};
managers.Add(manager);
}
其他的
{
如果(!manager.Employees.Contains(EmployeeId))
{
manager.Employees.Add(EmployeeId);
}
}
}
问题是,如果一位经理的员工列表中有另一位经理,我需要将第二位经理的员工添加到第一位经理的员工列表中,如果这些员工中的任何一位也是经理,我也需要添加他们,这将涉及多个层次

我想这需要某种递归,我尝试过的一切都变得过于复杂,效率低下

我是否应该使用其他东西,而不是包含列表的对象列表?
或者有人能给我指出正确的方向吗

您可以在xml linq中使用字典在一条指令中完成:

using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            Dictionary<int, List<int>> dict = doc.Descendants("Record")
                .GroupBy(x => (int)x.Element("ManagerId"), y => (int)y.Element("EmployeeId"))
                .ToDictionary(x => x.Key, y => y.ToList());
        }
    }
}
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序1
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
XDocument doc=XDocument.Load(文件名);
Dictionary dict=文档子体(“记录”)
.GroupBy(x=>(int)x.Element(“ManagerId”),y=>(int)y.Element(“EmployeeId”))
.ToDictionary(x=>x.Key,y=>y.ToList());
}
}
}

性能损失的原因如下:

Manager=managers.Find(m=>m.Id==ManagerId)

该行对列表中的每个员工调用一次,其实现是循环并返回第一个匹配项。相反,您需要设置一个
字典来包含您的记录。假设没有重复记录(即
Id
属性相同的记录),则以下操作将起作用:

public class Manager
{
    public readonly int ManagerId;
    public readonly int EmployeeId;
    public readonly List<int> Employees = new List<int>();

    public Manager(int employeeId, int managerId) {
        this.ManagerId = managerId;
        this.EmployeeId = employeeId;
    }
}

请注意,我将更新
经理的构造函数,以接受员工和经理ID,并初始化列表。

在添加员工列表之前,是否有原因检查员工列表是否包含该员工(即,您是否从服务中获得重复记录)?@theMayer Yes,有重复的记录,有多个经理的记录,他们有相同的员工,还有他们自己作为经理的员工。好的,所以写清理逻辑意味着你必须定义这是什么。一个以自我为管理者的员工将导致一个无休止的循环,除非你能解决这个问题。注意,我还没有测试过这一点——你可以做到。由于int的行为方式(即value从不为null),您可能会遇到一些奇怪的情况,即员工没有经理(顶级根)。这是一个非常优雅的解决方案。如果没有重复的记录,它将按原样完美地工作。不过,我想我应该能够适应我的需要,非常感谢!使用散列集而不是列表可以最好地消除重复项。是的,你是对的。另一个问题是,在创建字典时,同一名员工为不同的经理拥有多个记录。OPs希望为每个经理提供一份员工列表,这就是我提供的。@jdweng感谢您的回答,这比我的回答要好得多。除了您提供的内容之外,我要求的是一种递归检查经理的员工是否也是经理的方法,如果是,请将他们的员工添加到父经理。
var dict = records.Select(o => new Manager(o.EmployeeId, o.ManagerId))
                  .ToDictionary(o => o.EmployeeId);
foreach (var record in records)
{
    Manager manager;
    dict.TryGetValue(record.ManagerId, out manager);
    // recursively walk up the tree and add the record to each parent, etc.
    while (manager != null) {
        manager.Employees.Add(record.EmployeeId);
        dict.TryGetValue(manager.ManagerId, out manager);
    }
}