2009-03-23 3 views
1

J'ai une table qui a une structure arborescente en elle-même.Comment obtenir des données de table structurées en arbre par linq?

Id ParentId Name 
---------------- 
1 null x 
2 null y 
3 null z 
4 null t 
5  1  xx 
6  1  xy 
7  1  xz 
8  2  yx 
9  2  yy 
10 9  yyx 
11 10 yyxx 
12 11 yyxxx 

Je souhaite récupérer le sous-arbre entier sous un noeud racine. Lorsque mon nœud racine est "x", je veux obtenir l'ensemble des nœuds {1, 5, 6, 7, 10, 11, 12}. Comment puis-je faire ça par linq?

Répondre

1

Si vous pouvez changer la structure de la table pour ajouter des champs supplémentaires, alors une approche que j'ai utilisée dans le passé est d'avoir un champ "Chemin", qui contient une liste d'ID séparés par des virgules.

ID ParentID Name  Path 
-- -------- ----  ---- 
1  null  x   1 
2  null  y   2 
3  null  z   3 
4  null  t   4 
5  1   xx  1,5 
6  1   xy  1,6 
7  1   xz  1,7 
8  2   yx  2,8 
9  2   yy  2,9 
10 9   yyx  2,9,10 
11 10   yyxx  2,9,10,11 
12 11   yyxxx  2,9,10,11,12 

Ensuite, vous pouvez interroger en fonction du champ de chemin en utilisant LIKE (ou StartsWith dans LINQ)

Dans votre question, vous dites que vous voulez obtenir {1, 5, 6, 7, 10, 11, 12}, mais ces ID font partie de deux sous-arbres différents, si je l'ai bien lu.

Pour obtenir "x" et tous ses enfants ...

where Path = "1" || Path.StartsWith("1,") 

obtenir juste les enfants x ...

where Path.StartsWith("1,") 
+0

Belle solution, certains, comme moi, pensent que "simple" est le meilleur! –

0
/// <summary> 
    /// Allows to recursively select descendants as plain collection 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="source"></param> 
    /// <param name="DescendBy"></param> 
    /// <returns></returns> 

    public static IEnumerable<T> Descendants<T>(
     this IEnumerable<T> source, Func<T, IEnumerable<T>> DescendBy) 
    { 
     foreach (T value in source) 
     { 
      yield return value; 

      foreach (var child in DescendBy(value).Descendants(DescendBy)) 
      { 
       yield return child; 
      } 
     } 
    } 
utilisation

: node.children.Descendants (node => node.children);

0

Vous devez effectuer jointure interne dans LINQ avec le tableau lui-même comme suit:

from root in TableName 
join subnodes in TableName on root.Id equals subnodes.ParentId 
select new { Name } 

Cela permet de récupérer tous les enregistrements qui ID parent correspond à Id avec la même table renommée comme sous-noeuds

Merci

Questions connexes