创建分层类结构,循环遍历数据表,然后添加父和子以及返回对象

cWi*_*ilk 4 c# hierarchy

我想创建一个类结构,它可以表示以下所有相同类型的对象的heirarchichal结构

-Parent1
- - Child1 
- - - ChildA of Child1
- - - ChildB of Child1
- - Child2 
- - - ChildA of Child2
- - - ChildB of Child2
- Parent2
Run Code Online (Sandbox Code Playgroud)

数据表行具有ID,ParentID,名称和级别

父级为0,子级为1,ChildA为2,依此类推

我能够将数据从数据库返回到数据表,但是在创建类结构然后填充对象的任何帮助之后我都会非常感激

Mar*_*age 9

以下是使用LINQ如何执行此操作的示例.首先是一个样本数据表.我假设顶级项目的父ID为0.

var dataTable = new DataTable();
dataTable.Columns.Add("Id", typeof(Int32));
dataTable.Columns.Add("ParentId", typeof(Int32));
dataTable.Columns.Add("Name", typeof(String));
dataTable.Rows.Add(new Object[] { 1, 0, "A" });
dataTable.Rows.Add(new Object[] { 2, 1, "B" });
dataTable.Rows.Add(new Object[] { 3, 1, "C" });
dataTable.Rows.Add(new Object[] { 4, 0, "D" });
dataTable.Rows.Add(new Object[] { 5, 4, "E" });
Run Code Online (Sandbox Code Playgroud)

表示每个数据项的类:

class Item {

  public Int32 Id { get; set; }

  public String Name { get; set; }

  public IEnumerable<Item> Children { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

获取特定项目的子项的函数:

IEnumerable<DataRow> GetChildren(DataTable dataTable, Int32 parentId) {
  return dataTable
    .Rows
    .Cast<DataRow>()
    .Where(row => row.Field<Int32>("ParentId") == parentId);
}
Run Code Online (Sandbox Code Playgroud)

用于创建包括子集合的项的函数.此函数将递归层次结构:

Item CreateItem(DataTable dataTable, DataRow row) {
  var id = row.Field<Int32>("Id");
  var name = row.Field<String>("Name");
  var children = GetChildren(dataTable, id)
    .Select(r => CreateItem(dataTable, r))
    .ToList();
  return new Item { Id = id, Name = name, Children = children };
}
Run Code Online (Sandbox Code Playgroud)

获取顶级项目行的函数:

IEnumerable<DataRow> GetTopLevelRows(DataTable dataTable) {
  return dataTable
    .Rows
    .Cast<DataRow>()
    .Where(row => row.Field<Int32>("ParentId") == 0);
}
Run Code Online (Sandbox Code Playgroud)

把它们放在一起:

var items = GetTopLevelRows(dataTable)
  .Select(row => CreateItem(dataTable, row))
  .ToList();
Run Code Online (Sandbox Code Playgroud)