2010-04-01 5 views
3

J'ai une table avec deux colonnes, GroupId et ParentId (les deux sont GUIDS). La table forme une hiérarchie donc je peux chercher une valeur dans le "GroupId" classé, quand je l'ai trouvé je peux regarder son ParentId. Ce ParentId apparaîtra également dans le GroupId d'un enregistrement différent. Je peux l'utiliser pour remonter l'arborescence de la hiérarchie depuis n'importe quel point jusqu'à la racine (root est un GUID vide). Ce que je voudrais faire, c'est obtenir une liste d'enregistrements quand je connais un GroupId. Ce serait l'enregistrement avec le GroupId et tous les parents de retour à l'enregistrement racine. Est-ce possible avec Linq et si oui, quelqu'un peut-il fournir un extrait de code?Marche d'une table hiérarchique avec Linq

Répondre

5

LINQ n'est pas conçu pour gérer la sélection récursive.

Il est certainement possible d'écrire votre propre méthode d'extension pour compenser cela dans LINQ to Objects, mais j'ai trouvé que LINQ to Entities n'aime pas la fonctionnalité qui n'est pas facilement traduite en SQL.

Edit: Bizarrement, LINQ to Entities ne se plaint pas de prise de Matt Warren sur récursion LINQ here. Vous pourriez faire:

var result = db.Table.Where(item => item.GroupId == 5) 
        .Traverse(item => db.Table.Where(parent 
                 => item.ParentId == parent.GroupId)); 

en utilisant la méthode d'extension définie ici:

static class LinqExtensions 
{ 
    public static IEnumerable<T> Traverse<T>(this IEnumerable<T> source, 
              Func<T,IEnumerable<T>> selector){ 
    foreach(T item in source){ 
     yield return item; 
     IEnumerable<T> children = selector(item); 
     foreach (T child in children.Traverse(selector)) 
     { 
      yield return child; 
     } 
    } 
} 

Performace peut être pauvre, cependant.

1

C'est certainement possible avec Linq, mais vous devez faire un appel DB pour chaque niveau de la hiérarchie. Pas exactement optimal.

0

Les autres répondants ont raison: la performance va être très mauvaise, car vous devrez faire plusieurs allers-retours. Cela dépendra un peu de votre cas particulier, cependant - votre arbre est profond et les gens vont effectuer cette opération souvent, par exemple.

Vous pouvez être bien servi en créant une procédure stockée qui le fait (en utilisant un CTE), et en le câblant dans le Concepteur d'Entités pour retourner votre Entité particulièrement définie.

+0

Pouvez-vous me diriger dans la direction de quelques informations concernant comment faire ceci? – Evildommer5

Questions connexes