Menú dinámico desde base de datos con Sql Server y ASP.Net - Parte I

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.
La estructura de la tabla seria la siguiente:

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
)


Tenemos un código para identificar el ítem, descripción, url a la que nos va a direccionar, nivel (1, 2 o 3), código del ítem padre, orden dentro del menú (no todos los menú se ordenan de forma alfabética), los campos NLEFT y NRIGHT que son los índices que nos a permitir relacionar los padres con los hijos.
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

AS
BEGIN



-- 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:

osiel leiva dijo...

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

javier dijo...

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....