如果遞歸函數的全套工作是確定的,則以下應該工作。我把它一起扔在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; }
}
值得注意的是,您應該非常小心地使用這種遞歸方式,不好的數據可能會導致無限循環;也就是說,如果實體A具有父實體B,該實體B具有父實體A,並且具有父實體A等。 –
由於該功能不斷地在父母和子女的集合中被分割並且只有子女被髮送,所以情況不應該發生。當它到達有壞父母的孩子時,該父母不在子集內。 –
啊,好點。我現在看到了。 –