I have an entity called Category and the entity contains a IEnumerable called ChildCategories. A category can have these child categories which can have it\'s own child cate
You won't be able to do something like this with just LINQ alone; LINQ doesn't have any support for traversing an unknown level of nodes out-of-the-box.
Additionally, you don't have any real way of flattening the structure, the number of properties that is required is unknown (as it's tied to the tree depth, which is also unknown).
I'd recommend using iterators in C# to flatten the tree, something like this:
static IEnumerable Flatten(this IEnumerable source,
Func> childrenSelector)
{
// Do standard error checking here.
// Cycle through all of the items.
foreach (T item in source)
{
// Yield the item.
yield return item;
// Yield all of the children.
foreach (T child in childrenSelector(item).
Flatten(childrenSelector))
{
// Yield the item.
yield return child;
}
}
}
Then, you can call the extension method and place the results in a List; it's about as flat as you are going to get.
Note, you could very easily throw a StackOverflowException if the hierarchy is deep enough. To that end, you'd really want to use this non-recursive method:
static IEnumerable Flatten(this IEnumerable source,
Func> childSelector)
{
// Do standard error checking here.
// Create a stack for recursion. Push all of the items
// onto the stack.
var stack = new Stack(source);
// While there are items on the stack.
while (stack.Count > 0)
{
// Pop the item.
T item = stack.Pop();
// Yield the item.
yield return item;
// Push all of the children on the stack.
foreach (T child in childSelector(item)) stack.Push(child);
}
}
The Stack
Also, you can change the Stack to Queue
If you need a very specific order, I'd only recommend changing the ordering in the method if you have a large number of items that need to be traversed which makes calling OrderBy on the return value prohibitive.