Vous pouvez également utiliser une solution pure SQL; Voici un exemple pour SQL Server. Il ne serait pas difficile de le réécrire pour un autre gestionnaire de base de données:
/* Create table */
CREATE TABLE dbo.Nodes (ID int NOT NULL PRIMARY KEY, Parent int)
/* Insert sample data */
INSERT INTO Nodes VALUES (1,NULL)
INSERT INTO Nodes VALUES (2,1)
INSERT INTO Nodes VALUES (3,2)
INSERT INTO Nodes VALUES (4,3)
INSERT INTO Nodes VALUES (5,NULL)
INSERT INTO Nodes VALUES (6,5)
/* Create recursive function */
CREATE function dbo.fn_Root(@ID int) returns int
AS BEGIN
DECLARE @R int
SELECT @R = CASE WHEN Parent IS NULL THEN ID
ELSE dbo.fn_Root(Parent)
END
FROM Nodes
WHERE id = @id
RETURN @R
END
/* Query the table */
SELECT ID, Parent, dbo.fn_Root(ID) AS Root
FROM Nodes
/* Also, in SQL Server you can create a calculated column */
ALTER TABLE Nodes ADD Root AS dbo.fn_Root(id)
Ceci est la version de base. Mais celui-ci échouerait si vos données avaient des boucles fermées (pas une arborescence). Pour empêcher le code d'entrer dans une boucle sans fin, la fonction pourrait être améliorée comme ceci:
CREATE function dbo.fn_Root(@ID int, @Initial int) returns int
AS BEGIN
DECLARE @R int
DECLARE @Parent int
SELECT @Parent = Parent FROM Nodes WHERE ID = @ID
IF @Parent IS NULL
SELECT @R = @ID /* No parent, the root is the node itself */
ELSE
IF @Parent = @Initial
/* We have returned to initial node: endless loop. We return NULL to indicate no root exists */
SELECT @R = NULL
ELSE
/* The root will be the root of the parent node */
SELECT @R = dbo.fn_Root(@Parent,@Initial)
RETURN @R
END
/* Query the table */
SELECT ID, Parent, dbo.fn_Root(ID,ID) AS Root FROM Nodes
Avec cette modification, si la fonction retourne NULL, il indique que le nœud fait partie d'une boucle, et il n'a pas Noeud principal.
Voulez-vous dire d'avoir des objets qui ont eux-mêmes comme parents? –
Vous voulez dire une commande? Si vous voulez un IEnumerable de tous les enfants, vous pouvez choisir * de la table où parent n'est pas null, donc il doit y avoir plus à votre question ... – Kendrick
Le parent de la ligne 2 est la ligne 2? Aie. – Andomar