Turning a flat nested set into a hierarchy So I have categories in my database and I've implemented the Nested set model. I'm reading the categories as a flat structure and then I'm turning it into a hierarchy in memory, mapping each entity to a DTO.

Here's my code:

public async Task&lt;IActionResult&gt; GetCategories()
{
    var categories = (List&lt;Category&gt;)await _categoryService.GetAllAsync();

    var categoryDtos = GetCategoryDtosHierarchy(categories, null);

    categoryDtos.RemoveAll(x =&gt; x.Depth &gt; 0); // Terrible

    return Ok(categoryDtos);
}

private List&lt;CategoryDto&gt; GetCategoryDtosHierarchy(List&lt;Category&gt; categories, Category parent)
{
    var categoryDtos = new List&lt;CategoryDto&gt;();
    var filteredCategories = categories;

    if (parent != null)
    {
        filteredCategories = categories.Where(x =&gt; x.Depth == (parent.Depth + 1) &amp;&amp;
                                                   x.Left &gt; parent.Left &amp;&amp;
                                                   x.Right &lt; parent.Right).ToList();
    }

    foreach (Category filteredCategory in filteredCategories)
    {
        var categoryDto = new CategoryDto
        {
            Id = filteredCategory.Id,
            Name = filteredCategory.Name,
            Depth = filteredCategory.Depth,
            SubCategories = GetCategoryDtosHierarchy(categories, filteredCategory)
        };

        categoryDtos.Add(categoryDto);
    }

    return categoryDtos;
}


So everything works but it feels like somewhat an awkward solution. When the GetCategoryDtosHierarchy(categories, null); line returns it not only returns the categories with their subcategories but every level below like so:

[
  {
    "name": "Clothing",
    "depth": 0,
    "subcategories": [
      {
        "name": "Men's",
        "depth": 1,
        "subcategories": [
          {
            "name": "Suits",
            "depth": 2,
            "subcategories": []
          }
        ]
      },
      {
        "name": "Women's",
        "depth": 1,
        "subcategories": []
      }
    ]
  },
  {
    "name": "Men's", // Not supposed to be here
    "depth": 1,
    "subcategories": [
      {
        "name": "Suits",
        "depth": 2,
        "subcategories": []
      }
    ]
  },
  {
    "name": "Women's", // Not supposed to be here
    "depth": 1,
    "subcategories": []
  },
  {
    "name": "Suits", // Not supposed to be here
    "depth": 2,
    "subcategories": []
  }
]


And it has forced me to run the categoryDtos.RemoveAll(x =&gt; x.Depth &gt; 0); in order to get rid of the excess. I've thought about putting both calls in a new method but I feel like there might be a better solution than this hack.
What about idea (and removing categoryDtos.RemoveAll(x =&gt; x.Depth &gt; 0); // Terrible):

if (parent != null)
{
    filteredCategories = categories.Where(x =&gt; x.Depth == (parent.Depth + 1) &amp;&amp;
                                               x.Left &gt; parent.Left &amp;&amp;
                                               x.Right &lt; parent.Right).ToList();
}
else
{
    filteredCategories = categories.Where(x =&gt; x.Depth == 0).ToList();
}


Or, if the function is used somwhere else as well, maybe additional parameter to function like bool onlyTopLevel.