2014-02-06 3 views
0

Как создать сухарики для категорий с неограниченными подкатегориями, указанными родителями с их столбцом родительской?Как создать сухарь для категорий и подкатегорий с помощью linq

Представьте себе следующие элементы таблицы:

id name  parentid 
========================= 
1  animal NULL 
2  veg  NULL 
3  mineral NULL 
4  doggie 1 
5  kittie 1 
6  horsie 1 
7  gerbil 1 
8  birdie 1 
9  carrot 2 
10 tomato 2 
11 potato 2 
12 celery 2 

ответ

1

Если рекурсивная функция работает на полном наборе в порядке, то должно работать. Я бросил его вместе в 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; } 
} 
+0

Стоит отметить, что вы должны быть очень осторожны с использованием рекурсии таким образом, плохие данные могут привести к бесконечной петле; то есть, если Entity A имеет родительскую Entity B, которая имеет родительскую Entity C, которая имеет родительскую Entity A и т. д. –

+0

Поскольку функция непрерывно делится на множество родителей и детей, и только дети отправляются вперед, это ситуации не должно происходить. К тому времени, когда он достигнет ребенка с плохим родителем, этот родитель не находится в подмножестве. –

+0

Ах, хорошая точка. Я вижу это сейчас. –

Смежные вопросы