Вот пример того, как это сделать с помощью LINQ. Сначала нужно использовать файл sampe. Я предполагаю, что элементы верхнего уровня имеет родительский идентификатор 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" });
класс для представления каждого элемента данных:
class Item {
public Int32 Id { get; set; }
public String Name { get; set; }
public IEnumerable<Item> Children { get; set; }
}
Функции для получения детей определенного пункта:
IEnumerable<DataRow> GetChildren(DataTable dataTable, Int32 parentId) {
return dataTable
.Rows
.Cast<DataRow>()
.Where(row => row.Field<Int32>("ParentId") == parentId);
}
Функция создания элемента, включая дочернюю коллекцию. Эта функция будет рекурсия вниз по иерархии:
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 };
}
Функция для получения ряда элементов верхнего уровня:
IEnumerable<DataRow> GetTopLevelRows(DataTable dataTable) {
return dataTable
.Rows
.Cast<DataRow>()
.Where(row => row.Field<Int32>("ParentId") == 0);
}
Собирает все вместе:
var items = GetTopLevelRows(dataTable)
.Select(row => CreateItem(dataTable, row))
.ToList();
Мои типов здесь - Есть Child1 и Child2 разные? – Dave
Как эта иерархия представлена в вашей таблице данных? Можете ли вы предоставить и пример? – digEmAll
Родители и дети все одного типа – cWilk