using System.Collections.Generic;
public int Id { get; set; }
public string Name { get; set; }
public int? Parent { get; set; }
public override string ToString() {
return "[" + Id + " - " + Name + "]";
public int Deep { get; set; }
public static void Main()
Console.WriteLine("Hello World");
var products = new List<ProductDTO>();
products.Add(new ProductDTO() { Id = 7, Name = "Child One", Parent = 3 });
products.Add(new ProductDTO() { Id = 10, Name = "Child One", Parent = 4 });
products.Add(new ProductDTO() { Id = 8, Name = "Child Three", Parent = 1 });
products.Add(new ProductDTO() { Id = 9, Name = "Child Two", Parent = 2 });
products.Add(new ProductDTO() { Id = 1, Name = "Product One" });
products.Add(new ProductDTO() { Id = 2, Name = "Product Two" });
products.Add(new ProductDTO() { Id = 6, Name = "Child Two", Parent = 1 });
products.Add(new ProductDTO() { Id = 4, Name = "Child One", Parent = 1 });
products.Add(new ProductDTO() { Id = 5, Name = "Child One", Parent = 2 });
products.Add(new ProductDTO() { Id = 3, Name = "Product Three" });
var ordered = GetOrderedList(products, null, 0);
foreach(var item in ordered) {
for(int i = 0; i < item.Deep; i++) {
Console.Write(item.ToString());
public static List<ProductDTO> GetOrderedList(List<ProductDTO> Items, int? root, int deep) {
var result = new List<ProductDTO>();
foreach(var item in Items.Where(x => x.Parent == root).OrderBy(x => x.Id)) {
result.AddRange(GetOrderedList(Items, item.Id, deep + 1));