如何从平面CSV数据中读取树(父子)

本文关键字:读取 父子 数据 平面 CSV | 更新日期: 2023-09-27 18:05:50

我有一个类Employee:

public class Employee
{
    public Employee()
    {       
    }
    public int Id { get; set; }
    public string Name { get; set; }
    public Employee Manager { get; set; }
}

和一个包含所有员工的csv文件,一行的第一部分是Id,第二部分是名称,第三部分是经理的Id,如果它是空的,那么员工没有经理:

2;John;1    
1;James;    
3;Linda;1

我创建了一个类CsvReader,在这个类中我有一个方法GetEmployees,问题是我不能分配一个值给属性管理器!

...
 var lines = File.ReadAllLines(this.FilePath);
 foreach (var line in lines)
 {
 var parts = line.Split(';');
 var emp = new Employee();
 emp.Id = int.parse(parts[0]);
 emp.Name = parts[1];
 emp.Manager = ????
 }
 return employees;
}

我希望问题已经解决了

如何从平面CSV数据中读取树(父子)

这可以通过以下步骤解决:

  1. 读取所有记录;存储Manager Id(但不分配Manager值)。为简单起见,只需在Employee类型中添加另一个属性。

  2. 创建Employee对象后,将其添加到Dictionary<int,Employee>中,其中键为Employee ID。

  3. 读入所有记录后,循环遍历Employees字典(顺序无关紧要),并为每个Employee分配Manager值。(Manager Employee对象为employeeDict[employee.ManagerId])

创建一个Dictionary<int, Employee>,存储员工Id和代表该员工的Employee类实例之间的映射,并使用它来获取对经理的引用:

var lines = File.ReadAllLines(this.FilePath);
var mapping = new Dictionary<int, Employee>();
foreach (var line in lines)
{
    var parts = line.Split(';');
    var emp = new Employee();
    emp.Id = int.parse(parts[0]);
    emp.Name = parts[1];
    if(!string.NullOrEmpty(parts[2]))
        emp.Manager = mapping[int.Parse(parts[2])];
    mapping[emp.Id] = emp;
}

它不是防弹的,它要求CSV中的数据是正确的:

  • 没有ManagerId指向不存在的经理的员工
  • manager必须在其所有报告
  • 之前的文件中声明。

但它应该给你一个如何解决你的问题的想法。