I recently posted some code on Code Review which answers this question. Here it is below, slightly modified for your table. I have tried to meet your needs by using a DataTable as the input, but I haven't used DataTables with LINQ before so you may need to edit slightly.
public TreeNode GenerateCategoriesTree(DataTable dt) { var s = new Stack<TreeNodeAndId>(); var categories = dt.AsEnumerable(); var rootCategory = categories.Single(o => o.Field<int?>("parents_id") == null); var rootNode = new TreeNode(rootCategory["category_name"].ToString(), rootCategory["category_id"].ToString()); s.Push(new TreeNodeAndId { Id = Convert.ToInt32(rootCategory["category_id"]), TreeNode = rootNode }); while (s.Count > 0) { var node = s.Peek(); var current = categories.FirstOrDefault(o => o.Field<int?>("parents_id") == node.Id); if (current == null) { s.Pop(); continue; } var child = new TreeNode(current["category_name"].ToString(), current["category_id"].ToString()); node.TreeNode.ChildNodes.Add(child); s.Push(new TreeNodeAndId { Id = Convert.ToInt32(current["category_id"]), TreeNode = child }); categories.Remove(current); } return rootNode; } struct TreeNodeAndId { public TreeNode TreeNode; public int? Id; }
If this doesn't build then at least I hope it will point you in the right direction.