Rick Rick - 2 months ago 6
C# Question

Sorting a list by parent/child relations ship so I have definitely processed a parent before I try to process the child

I have a system where people can sent me a


I need to do some mapping to my system and then save these to the database.

The incoming data is in this format:

public string ExternalCategoryID { get; set; }
public string ExternalCategoryName { get; set; }
public string ExternalCategoryParentID { get; set; }

The incoming list is in no particular order. If
is null then this is a top level category. The parent child relationship can be any depth - i.e. Technology > TVs > Samsung > 3D > 40" > etc > etc

When I'm saving I need to ensure I've already saved the parent - I can't save TVs until I have saved Technology. The
is likely to be an int but this has no relevance on the parent child relationship (a parent can have a higher or lower id than a child).

How can I order this list so I can loop through it and be certain that for any child, I have already processed it's parent.

The only way I can think of is to get all where
ExternalCategoryParentID == null
then get all where the
is in this "Top Level" list, then get the next set of children... etc. but this can't be the best solution. I'd prefer to sort first, then have a single loop to process. I have found this post, but it relies on
which isn't relevant to me.


Turns out it wasn't so difficult after all. I wrote this function to do it - you pass in the original list and it will return a sorted list.

It works by looping through the list checking if there are any items in the list that have id == current items parentid. If there is one, we ignore that item and continue. if there aren't any, we add the current item to the sortedList and remove it from the original list and continue. This ensures that items are inserted in the sorted list after their parent.

private List<HeisenbergProdMarketplaceCategory> SortByParentChildRelationship(List<HeisenbergProdMarketplaceCategory> heisenbergMarketplaceCategories)
    List<HeisenbergProdMarketplaceCategory> sortedList = new List<HeisenbergProdMarketplaceCategory>();

    //we can check that a category doesn't have a parent in the same list - if it does, leave it and continue
    //eventually the list will be empty
    while(heisenbergMarketplaceCategories.Count > 0)
        for (int i = heisenbergMarketplaceCategories.Count-1; i >= 0; i--)
            if (heisenbergMarketplaceCategories.SingleOrDefault(p => p.ExternalCategoryID == heisenbergMarketplaceCategories[i].ExternalCategoryParentID) == null)

    return sortedList;