Если рекурсивная функция работает на полном наборе в порядке, то должно работать. Я бросил его вместе в LINQPad. Магия - это рекурсивная функция GetBreadcrumbs. Я добавил третий боксер под собачкой.
void Main()
{
var list = new List<MyEntity>()
{
new MyEntity() { Id = 1, Name = "animal" },
new MyEntity() { Id = 2, Name = "veg" },
new MyEntity() { Id = 3, Name = "mineral" },
new MyEntity() { Id = 4, Name = "doggie", ParentId = 1 },
new MyEntity() { Id = 5, Name = "kittie", ParentId = 1 },
new MyEntity() { Id = 6, Name = "horsie", ParentId = 1 },
new MyEntity() { Id = 7, Name = "gerbil", ParentId = 1 },
new MyEntity() { Id = 8, Name = "birdie", ParentId = 1 },
new MyEntity() { Id = 9, Name = "carrot", ParentId = 2 },
new MyEntity() { Id = 10, Name = "tomato", ParentId = 2 },
new MyEntity() { Id = 11, Name = "potato", ParentId = 2 },
new MyEntity() { Id = 12, Name = "celery", ParentId = 2 },
new MyEntity() { Id = 13, Name = "boxer", ParentId = 4 },
};
var breadcrumbs = GetBreadcrumbs(list);
foreach (var breadcrumb in breadcrumbs)
Console.WriteLine(breadcrumb);
}
// This is where the Magic happens!
public IEnumerable<string> GetBreadcrumbs(IEnumerable<MyEntity> entities, int? parentId = null)
{
var parents = entities.Where(x => x.ParentId == parentId);
var children = entities.Where(x => x.ParentId != parentId);
foreach (var parent in parents)
{
yield return parent.Name;
foreach (var trail in GetBreadcrumbs(children, parent.Id))
yield return (parent.Name + " > " + trail);
}
}
public class MyEntity
{
public int Id { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
}
Стоит отметить, что вы должны быть очень осторожны с использованием рекурсии таким образом, плохие данные могут привести к бесконечной петле; то есть, если Entity A имеет родительскую Entity B, которая имеет родительскую Entity C, которая имеет родительскую Entity A и т. д. –
Поскольку функция непрерывно делится на множество родителей и детей, и только дети отправляются вперед, это ситуации не должно происходить. К тому времени, когда он достигнет ребенка с плохим родителем, этот родитель не находится в подмножестве. –
Ах, хорошая точка. Я вижу это сейчас. –