2012-05-01 1 views
3

Я действительно новичком в C#создать иерархическую структуру класса, проходные таблицы данных, а затем добавить родитель и ребенок и вернуть объект

Я хочу создать класс структуру, которая может представлять следующую heirarchichal структуру объектов всех из тот же самый тип

-Parent1 
- - Child1 
- - - ChildA of Child1 
- - - ChildB of Child1 
- - Child2 
- - - ChildA of Child2 
- - - ChildB of Child2 
- Parent2 

в DataTable строки имеют идентификатор, ParentId, имя и уровень

уровень вывода для Родитель, 1 для ребенка 1, 2 для childâ и так далее

Я могу вернуть данные из БД к DataTable, но я изо всех сил после этого любая помощь в создании структуры класса, а затем заселять объект будет высоко оценен

+0

Мои типов здесь - Есть Child1 и Child2 разные? – Dave

+0

Как эта иерархия представлена ​​в вашей таблице данных? Можете ли вы предоставить и пример? – digEmAll

+0

Родители и дети все одного типа – cWilk

ответ

9

Вот пример того, как это сделать с помощью 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(); 
+0

oops, я на самом деле использую набор данных, это сильно меняет ситуацию? – cWilk

+0

'DataSet' содержит коллекцию' Tables'. Выберите таблицу, содержащую данные. –

+0

ya, я понял это и использовал - return ResultSet.Tables [0], чтобы получить таблицу – cWilk

2

Учитывая информацию выше вы могли бы сделать это с просто один класс.

public class MyItem 
{ 
    public IList<MyItem> ChildItems{get;set;} 
} 

Здесь вы в основном получили объект, который может содержать коллекцию своего собственного типа, как ребенок, и, таким образом, эти дети могут содержать коллекции MyItem тоже как суб-ребенок.

Рассмотрим следующий пример:

var parentItem = new MyItem() 
var childItem = new MyItem(); 
var childChildItem = new MyItem(); 

childItem.ChildItems.Add(childChildItem); 
parentItem.ChildItems.Add(childItem); 

Есть более хорошие способы закодировать добавления элементов, но это ломает это достаточно логично для концепции, чтобы быть ясным.