2010-10-06 6 views
0

J'ai le tableau suivant, MenuItems, dans la base de données:Comment faire une requête récursive dans Linq2Sql?

ID ParentID Name 
--- --------- ----- 
1 0   Item 1 
2 1   Item 2 
3 1   Item 3 
4 0   Item 4 
5 3   Item 5 

Je veux écrire une méthode d'extension pour obtenir tous les éléments de menu à la racine de l'arbre. Quelque chose comme ceci:

public IQueryable<MenuItem> GetToRoot(this IQueryable<MenuItem> source, int menuItemID) 
{ 
    return from m in source 
      ???? 
      ???? 
      select m; 
} 

Si j'appelle cette méthode d'extension avec les données ci-dessus pour l'élément de menu avec ID 3, je devrais obtenir:

ID ParentID Name 
--- --------- ----- 
1 0   Item 1 
3 1   Item 3 

Est-ce possible avec Linq2Sql avec un seul appel à la base de données?

Répondre

1

Je ne pense pas que vous serez en mesure de le faire dans une seule requête, et voici ma pensée: la découverte du parent d'un élément nécessite effectivement une jointure de la table avec lui-même. Chaque niveau de menu supplémentaire nécessite une autre jointure de la table avec lui-même. Combien de jointures/niveaux supplémentaires aurez-vous besoin pour atteindre la racine? Vous ne saurez pas jusqu'à ce que vous effectuez chacun, non? Ainsi, que ce soit du côté de la base de données/SQL ou de LINQ to SQL, vous devrez prendre chaque étape une à la fois. Si vous savez que votre système de menu ne va pas au-delà d'une certaine profondeur, je suppose que vous pourriez configurer une requête LINQ to SQL qui rejoint la table avec lui-même ce nombre de fois, mais cela sonne moche. Ce que je suggérerais est de mettre en place une association de la table avec elle-même dans votre concepteur DBML, qui vous donnerait une propriété parentale EntityRef<> sur la classe. Puisque les cycles ne sont pas autorisés dans votre LoadOptions (et donc que le parent ne peut pas être préchargé), vous pouvez forcer la charge paresseuse du parent dans la méthode OnLoaded() partielle de l'entité.

Voici quelques questions pertinentes SO:

https://stackoverflow.com/questions/1435229/hierarchy-problem-replace-recursion-with-linq-join LINQ to SQL for self-referencing tables?

Voici un côté serveur/traitement SQL du problème:

http://www.sqlteam.com/article/more-trees-hierarchies-in-sql

ici est quelqu'un qui a écrit moi le code aide:

http://www.scip.be/index.php?Page=ArticlesNET18