如果递归函数的全套工作是确定的,则以下应该工作。我把它一起扔在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等。 –
由于该功能不断地在父母和子女的集合中被分割并且只有子女被发送,所以情况不应该发生。当它到达有坏父母的孩子时,该父母不在子集内。 –
啊,好点。我现在看到了。 –