2009-12-29 3 views
3

Cette question fait référence à http://www.matthidinger.com/archive/2009/02/08/asp.net-mvc-recursive-treeview-helper.aspxRemplissez une structure de données récursive à partir d'une base de données autoréférentiel Tableau

Disons que j'ai une table qui ressemble à ceci:

alt text http://blog2.matthidinger.com/ContentImages/ASP.NETMVCRecursiveTreeViewHelper_B445/image_3.png

Et j'ai données récursive structure qui ressemble à ceci:

public class TreeNode 
{ 
    public TreeNode(){} 
    public string NodeId { get; set; } 
    public string ParentId { get; set; } 
    public string Name { get; set; } 
    public IEnumerable<TreeNode> Children { get; } 
} 

Comment remplir cette structure de données récursive à partir de la table en utilisant Linq?

REMARQUE: Pour les besoins de cette question, veuillez supposer que j'ai déjà une table parfaitement efficace; c'est-à-dire qu'il est complètement résident en mémoire, ou qu'il est en cours d'accès en utilisant un CTE. Vraiment, je suis juste à la recherche des requêtes Linq pour l'obtenir de Linq à SQL DataContext à l'objet récursif. Je suis conscient que cela impliquera probablement un appel de fonction ForEach et récursif; Je ne peux pas vraiment comprendre.

Merci d'avance.

+0

Voir aussi: http://stackoverflow.com/questions/535436/linq-to-sql-recursively-get-children –

Répondre

1

Je pense que votre meilleure option est d'interroger la hierachie en SQL en utilisant CTE. LINQ2SQL et les données hiérarchiques/relationnelles ne se mélangent pas très bien. Voir Hierarchical data in Linq - options and performance.

+0

Je vois dans les exemples MSDN que cela produit une liste dans l'ordre hiérarchique correct. Cela me permet-il de parcourir la liste linéairement pour construire ma structure récursive, et est-ce la raison pour laquelle la performance est meilleure? –

+0

Les requêtes CTE sont le seul moyen de produire le jeu de résultats pour 'J'ai besoin de tous les enfants du nœud actuel, et les enfants des enfants et ainsi de suite' dans SQL. Ce n'est pas une question d'ordre (c'est juste un effet secondaire de l'exécution), mais la correction. Si vous pouvez vous permettre d'aller chercher la table * whole * dans le client, il n'y a pas besoin d'utiliser CTE, on peut simplement utiliser une requête ordinaire puis construire l'arbre de la mémoire. Aussi, si vous avez seulement besoin des enfants d'un nœud courant (par exemple pour instancier l'itérateur Childrens), alors il n'y a plus besoin de CTEs, un 'SELECT ... WHERE Parent = @ id' fera l'affaire. –

Questions connexes