Ich arbeite an einem DotNetNuke-Modul, das ein Navigationsmenü im Baumstil enthält.Rekursives SQL zum Erstellen eines DNN-Navigationsmenüs
Bis jetzt habe ich es funktioniert, in dem Sinne, dass Kind-Knoten mit ihren richtigen Eltern-Knoten verbunden sind, aber die Knoten-Geschwister sind immer noch außer Betrieb. Es gibt ein Feld namens TabOrder, mit dem die Reihenfolge der Geschwister bestimmt wird, aber aufgrund der Rekursion kann ich sie nicht richtig sortieren.
Ich versuche dies in einer gespeicherten SQL Server-Prozedur zu tun, was ein Fehler sein kann, aber ich fühle mich so nah, dass es eine Lösung geben muss. Hat jemand eine Idee, was ich falsch mache?
Ich würde mich über alle Ideen freuen, die Sie haben. Danke im Voraus.
Lösung:
fand ich endlich eine Lösung für meine Frage. Der Schlüssel war, eine Tab-Lineage (TabLevel + TabOrder) rekursiv von der Root-Registerkarte zu den Leaf-Tabs zu erstellen. Sobald das erstellt wurde, konnte ich die zurückgegebenen Datensätze ordnungsgemäß bestellen.
Als ich jedoch zurückkam, um dies zu posten, sah ich MarkXA die Antwort, die wahrscheinlich die beste Lösung ist. Ich wusste nicht, dass die Methode GetNavigationNodes überhaupt existiert.
Ich denke, er ist richtig, dass die Verwendung von GetNavigationNodes ist eine zukunftssichere Lösung, aber für den Moment werde ich meine SQL-basierte Lösung verwenden. --Was kann ich sagen? Ich lerne auf die harte Tour.
Hier ist sie:
ALTER procedure [dbo].[Nav_GetTabs]
@CurrentTabID int = 0
AS
--============================================================
--create and populate @TabLineage table variable with Tab Lineage
--
--"Lineage" consists of the concatenation of TabLevel & TabOrder, concatenated recursively from the root to leaf.
--The lineage is VERY important, making it possible to properly order the Tab links in the navigation module.
--This will be used as a lookup table to match Tabs with their lineage.
--============================================================
DECLARE @TabLineage table
(
TabID int,
Lineage varchar(100)
);
WITH TabLineage AS
(
--start with root Tabs
SELECT T.TabID, T.ParentID, CAST(REPLICATE('0', 5 - LEN(CAST(T2.[Level] as varchar(10)) + CAST(T2.TabOrder as varchar(10)))) + CAST(T2.[Level] as varchar(10)) + CAST(T2.TabOrder as varchar(10)) as varchar(100)) AS Lineage
FROM Tabs T
INNER JOIN Tabs T2 ON T.TabID = T2.TabID
INNER JOIN TabPermission TP ON T.TabID = TP.TabID
WHERE T.ParentID IS NULL
AND T.IsDeleted = 0
AND T.IsVisible = 1
AND TP.RoleID = -1
UNION ALL
--continue recursively, from parent to child Tabs
SELECT T.TabID, T.ParentID, CAST(TL.Lineage + REPLICATE('0', 5 - LEN(CAST(T2.[Level] as varchar(10)) + CAST(T2.TabOrder as varchar(10)))) + CAST(T2.[Level] as varchar(10)) + CAST(T2.TabOrder as varchar(10)) as varchar(100)) AS Lineage
FROM Tabs T
INNER JOIN Tabs T2 ON T.TabID = T2.TabID
INNER JOIN TabPermission TP ON T.TabID = TP.TabID
INNER JOIN TabLineage TL ON T.ParentID = TL.TabID
WHERE T.IsDeleted = 0
AND T.IsVisible = 1
AND TP.RoleID = -1
)
--insert results of recursive query into temporary table
INSERT @TabLineage
SELECT TL.TabID, TL.Lineage FROM TabLineage TL ORDER BY TL.Lineage
OPTION (maxrecursion 10); --to increase number of traversed generations, increase "maxrecursion"
--============================================================
--create and populate @Ancestor table variable with @CurrentTab ancestors
--
--"Ancestors" are Tabs following the path from @CurrentTab to the root Tab it's descended from (inclusively).
--These are Tab links we want to see in the navigation.
--============================================================
DECLARE @Ancestor table
(
TabID int
);
WITH Ancestor AS
(
--start with @CurrentTab
SELECT T.TabID, T.ParentID FROM Tabs T WHERE T.TabID = @CurrentTabID
UNION ALL
--continue recursively, from child to parent Tab
SELECT T.TabID, T.ParentID
FROM Ancestor A INNER JOIN Tabs T ON T.TabID = A.ParentID
)
--insert results of recursive query into temporary table
INSERT @Ancestor
SELECT A.TabID FROM Ancestor A
OPTION (maxrecursion 10); --to increase number of traversed generations, increase "maxrecursion"
--============================================================
--retrieve Tabs to display in navigation
--This section UNIONs three query results together, giving us what we want:
-- 1. All Tabs at Level 0.
-- 2. All Tabs in @CurrentTab's lineage.
-- 3. All Tabs which are children of Tabs in @CurrentTab's lineage.
--============================================================
WITH TabNav (TabID, TabLevel, TabName, Lineage) AS
(
--retrieve all Tabs at Level 0 -- (Root Tabs)
(SELECT T.TabID, T.[Level] AS TabLevel, T.TabName, TL.Lineage
FROM Tabs T
INNER JOIN TabPermission TP ON (T.TabID = TP.TabID AND TP.RoleID = -1)
INNER JOIN @TabLineage TL ON T.TabID = TL.TabID
WHERE T.IsDeleted = 0
AND T.IsVisible = 1
AND T.[Level] = 0
UNION
--retrieve Tabs in @CurrentTab's lineage
SELECT T.TabID, T.[Level] AS TabLevel, T.TabName, TL.Lineage
FROM Tabs T
INNER JOIN TabPermission TP ON (T.TabID = TP.TabID AND TP.RoleID = -1)
INNER JOIN @Ancestor A ON T.TabID = A.TabID
INNER JOIN @TabLineage TL ON T.TabID = TL.TabID
WHERE T.IsDeleted = 0
AND T.IsVisible = 1
UNION
--retrieve Tabs which are children of Tabs in @CurrentTab's lineage
SELECT T.TabID, T.[Level] AS TabLevel, T.TabName, TL.Lineage
FROM Tabs T
INNER JOIN TabPermission TP ON (T.TabID = TP.TabID AND TP.RoleID = -1)
INNER JOIN @Ancestor A ON T.ParentID = A.TabID
INNER JOIN @TabLineage TL ON T.TabID = TL.TabID
WHERE T.IsDeleted = 0
AND T.IsVisible = 1)
)
--finally, return the Tabs to be included in the navigation module
SELECT TabID, TabLevel, TabName FROM TabNav ORDER BY Lineage;
--============================================================
Die Abfrage war hilfreich, dass ich ein Bootstrap-Menü mock machen musste. Das SQL war gut genug, um mir zu helfen, Listen-Tags zu erzeugen. – Greg