Menú dinámico desde base de datos con Sql Server y ASP.Net
Vamos a ver mi solución al momento de crear un menú dinámico con datos que se encuentran almacenados en una base de datos, para nuestro caso Sql Server.
Primero vamos a ver la parte de datos que se va a centrar en una tabla para almacenar las opciones del menú, el diseño está orientado a tener tres niveles el primero de aplicación, el segundo de menú y el tercero de comando, es decir vamos a tener una estructura que va a permitir almacenar opciones para varias aplicaciones (que es mi caso, necesito tener centralizada la seguridad de tres aplicaciones y asignar opciones dentro de las tres para un usuario.)
Mi solución es una variante simplificada del siguiente proyecto http://www.codeproject.com/KB/database/tree_olap.aspx, digo simplificada porque este ejemplo sirve para arboles de cualquier nivel, utiliza triggers para implementarlo y es súper eficiente al momento de recuperar estructuras jerárquicas, mi simplificación viene por el lado de el número de niveles del árbol es fijo, solamente tres, no se utilizan triggers porque voy a fijar las identificaciones de los nodos dentro de intervalos fijos, pero el concepto si se implementa para la recuperación de los arboles.
CREATE TABLE [dbo].[menuitem](
[CODIGO] [int] NOT NULL,
[DESCRIPCION] [varchar] (
200) NOT NULL,
[URL] [varchar]
(200) NOT NULL,
[NIVEL] [int]
NULL,
[CODIGOPADRE] [int]
NULL,
[ORDEN] [int]
NOT NULL,
[NLEFT] [int]
NOT NULL,
[NRIGHT] [int]
NOT NULL)
En el siguiente SP tenemos la simplificación del trigger del artículo que comentaba que nos permite insertar los nodos dentro del árbol del menú, el concepto es simple, se asignan ID de 100 en 100 para cada comando del menú (es decir al nivel 2) de tal manera que cada uno tiene hasta 99 opciones, lo que me parece un número bastante grande de opciones.
ALTER
PROCEDURE ING_MENUITEM @OPCION VARCHAR(100)
, @COD_PADRE INT
, @NIVEL INT
ASBEGIN
-- CODIGO DE LA SIGUIENTE OPCIÓN
DECLARE @CODIGO int
DECLARE @NUM_ITEM INT
SELECT @NUM_ITEM = COUNT(CODIGO)
FROM MENUITEM
WHERE CODIGOPADRE = @COD_PADRE
IF (@NIVEL = 2)
SET @CODIGO = (@NUM_ITEM + 1 ) * 100
ELSE
SET @CODIGO = @COD_PADRE + @NUM_ITEM + 1
INSERT INTO menuitem([CODIGO]
,[DESCRIPCION]
,[URL]
,[NIVEL]
,[CODIGOPADRE]
,[ORDEN]
,[NLEFT]
,[NRIGHT])
VALUES
(@CODIGO
,@OPCION
,'a'
,3
,@COD_PADRE
,1
,@CODIGO
,@CODIGO + 1)
-- ACTUALIZAMOS EL VALOR MAXIMO DEL PADRE
UPDATE MENUITEM SET NRIGHT = @CODIGO
WHERE CODIGO = @COD_PADRE
END
Si queremos insertar un nodo nivel 2 deberíamos ejecutar lo siguiente EXEC ING_MENUITEM 'opcion 2',1,2 y para un hijo de este menú EXEC ING_MENUITEM 'opcion 21',200,3
Para recuperar toda la estructura de menú 200 ejecutamos el siguiente script
SELECT C.*
FROM
MENUITEM C
INNER
JOIN MENUITEM P ON C.NLEFT BETWEEN P.NLEFT AND P.NRIGHT
WHERE
P.CODIGO = 200
Y para recuperar todas las opciones de nivel 1, es decir a nivel de aplicación
SELECT C.*
FROM
MENUITEM C
INNER
JOIN MENUITEM P ON C.NLEFT BETWEEN P.NLEFT AND P.NRIGHT
WHERE
P.CODIGO = 1
Para poder consumir los datos desde una página ASP.NET, vamos a crear utilizar el siguiente SP, que nos va a apermitir consultar los elementos del menú
CREATE
PROCEDURE [CONS_MENUITEM] @MENU_CODIGO INT
AS
BEGIN
--@MENU CODIGO CORRESPONDE AL CODIGO DEL MENU PADRE
SELECT C.CODIGO
, C.DESCRIPCION
, C.URL
, C.NIVEL
, ISNULL(C.CODIGOPADRE,0) AS CODIGOPADRE
FROM TB_MENUITEM C
INNER JOIN TB_MENUITEM P ON C.MIT_NLEFT BETWEEN P.MIT_NLEFT AND P.MIT_NRIGHT
WHERE P.MIT_CODIGO = @MENU_CODIGO
END
Para poder llenar los datos en un control TreeView lo hacemos de forma recursiva como lo explico en el siguiente post http://wjama.blogspot.com/2008/03/llenar-treeview-de-forma-recursiva.html
2 comentarios:
Hola felicitaciónes por el tutorial, me gustaria saber si tienes algo mas especifico... es que nesecito llenar un treeview en aspx con visual web desde una bd de sql server... si tienes algo mas de información en la que me puedas ayudar te estaría muy agradecido..
Osiel Leiva
osiel_leiva@hotmail.com
hola, muy bueno tu aporte, pero sera posible llebar este codigo a asp clasico. Como mostrarlo en ASP, sera posible que se pueda... este es mi correo
goondam@gmail.com
Atte ud. Javier
de ante mano muchas gracias....
Publicar un comentario en la entrada