Firstly, ParentID should be an
int
, not a
string
Secondly, you don't need recursion at all, and provided your parent nodes are always defined before their children, you can use a single loop. (If it's a random order, then create a node collection first, and then loop through that afterwards:
class Chart
{
private static Dictionary<int, Chart> all = new Dictionary<int, Chart>();
public int ID { get; set; }
public string Name { get; set; }
public int ParentID { get; set; }
public List<Chart> Children { get; set; } = new List<Chart>();
private Chart(DataRow row)
{
ID = (int)row["ID"];
Name = (string)row["Name"];
ParentID = (int)row["ParentID"];
all[ID] = this;
}
public static Chart MakeTree(DataTable dt)
{
List<Chart> nodes = new List<Chart>();
Chart root = null;
foreach (DataRow row in dt.AsEnumerable())
{
Chart node = new Chart(row);
if (node.ParentID == 0)
{
if (root != null) throw new ArgumentException("Too many ROOT nodes: only one was expected.");
root = node;
}
else
{
if (root == null) throw new ArgumentException("ROOT node has not been defined: one is required.");
Chart parent = all[node.ParentID];
parent.Children.Add(node);
}
}
return root;
}
}
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("ParentID", typeof(int));
dt.Rows.Add(1, "A", 0);
dt.Rows.Add(2, "B", 1);
dt.Rows.Add(3, "C", 1);
dt.Rows.Add(4, "D", 2);
dt.Rows.Add(5, "E", 3);
dt.Rows.Add(6, "F", 4);
Chart root = Chart.MakeTree(dt);