none
Relación muchos a muchos RRS feed

  • Pregunta

  • Hola 

    Trabajo en una app Windows Forms, EF(code firts), VS 2019, SQL Server 2014

    Tengo el siguiente escenario

    Este diseño es un control de acceso al sistema por usuario, le detallo a continuación:

    • Permiso(Leer, Insertar, Actualizar, Borrar)
    • TipoObjeto(Administrador, Vendedor)
    • Objeto(las entidades o formularios)
    • ControlAcceso(Es la tabla intermedia que hace la relación entre Usuarios y Objetos)

    Generalmente trabajo con tablas intermedias pero solo contemplo los Ids de las tablas que hacen la relación pero esta vez es un caso particular que he tenido que agregar otro campo Permitir.

    Mi pregunta es la siguiente: ¿Se puede crear con EF code first una tabla intermedia que tenga una llave compuesta?, ¿sería posible o debería trabajar de otra manera?

    Saludos!


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú

    martes, 24 de diciembre de 2019 16:50

Respuestas

  • No, lo que quieres hacer no es una tabla intermedia con llave compuesta. Tu tabla intermedia tiene dos llaves simples. El problema es que contiene datos adicionales (los Permisos) además de las llaves. Y esto es algo que EF no soporta (los datos adicionales en una tabla intermedia), o al menos no lo soportaba en los tiempos de EF4, no sé si lo habrán añadido en alguna versión posterior.

    Así que si quieres usar EF con este diseño, la tabla ControlAcceso no la puedes tratar como tabla intermedia. Para que EF la soporte, tienes que tratarla como una tabla normal que casualmente tiene dos foreign keys que la conectan a otras dos tablas.

    Aparte de las dos Foreign Keys simples, probablemente querrás añadir a tu tabla una Primary Key, que posiblemente esté compuesta por los tres campos (las dos FKs más el campo Permitir, que presumiblemente permite varios permisos distintos por cada objeto y usuario, de lo contrario no sería de tipo int, e incluso sería superfluo). En este caso, la FK sí que sería una clave compuesta. Puedes declarar la clave primaria compuesta si quieres, pero si finalmente no vas a tratar la tabla como tabla intermedia sino como una tabla normal, tal vez te resulte más sencillo agregarle un ID de tipo Identity y usar éste como clave primaria.

    • Marcado como respuesta Pedro Ávila martes, 24 de diciembre de 2019 18:22
    martes, 24 de diciembre de 2019 18:17
    Moderador
  • Hola @Alberto

    Me quedo con la tabla ControlAcceso con la siguiente estructura {Id, UsuarioId, ObjetoId, Permitir} Id queda como llave primaria.

    Saludos!


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú

    martes, 24 de diciembre de 2019 18:24
  • hola

    >>Función: Leer, Insertar, Actualizar, Eliminar

    esas no son funciones

    las funciones podria ser: EditarUsuario, EditarArticulos, EliminarProducto, VerPreciosMayoristas, etc

    son funciones dentro de tu aplicacion

    entonces cuando le vas a mostrar el menu, o el boton al usuario para, por ejemplo, permitir eliminar un productos, validas si tiene esa funcion asociada segun su rol y le habilitas el boton o no

    lo mismo los menus, si tienes una pantalla de edicion de usuario, le muestras el item de menu si es que tiene la funcion "EditarUsuario"

    Igual las funciones se pueden complementar porque un usuario puede editar, pero no crear un usuario nuevo, por lo tanto tendras, imaginemos 3 funciones: CrearUsuario, EditarUsuario, EliminarUsuario

    estas 3 funciones las validas para mostrarle los menus o los botones dentro del form de usuarios

    las funciones por lo general son un verbo + un objeto sobre el cual aplica, por eso Crear + Usuario o Nuevo + Prestamo

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Marcado como respuesta Pedro Ávila lunes, 30 de diciembre de 2019 14:26
    lunes, 30 de diciembre de 2019 14:22
  • >>Control Acceso: se alimenta de la entidad ventana(son los formularios para administrar quien esta visible)

    esas tablas de control de acceso puede eliminarlas, no aplican si usas funciones

    la tabla de ventana no funciona, usas funciones no pienses en codigo para la autorizaciones, piensas en definir acciones sobre el sistema

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Marcado como respuesta Pedro Ávila lunes, 30 de diciembre de 2019 14:26
    lunes, 30 de diciembre de 2019 14:24

Todas las respuestas

  • No, lo que quieres hacer no es una tabla intermedia con llave compuesta. Tu tabla intermedia tiene dos llaves simples. El problema es que contiene datos adicionales (los Permisos) además de las llaves. Y esto es algo que EF no soporta (los datos adicionales en una tabla intermedia), o al menos no lo soportaba en los tiempos de EF4, no sé si lo habrán añadido en alguna versión posterior.

    Así que si quieres usar EF con este diseño, la tabla ControlAcceso no la puedes tratar como tabla intermedia. Para que EF la soporte, tienes que tratarla como una tabla normal que casualmente tiene dos foreign keys que la conectan a otras dos tablas.

    Aparte de las dos Foreign Keys simples, probablemente querrás añadir a tu tabla una Primary Key, que posiblemente esté compuesta por los tres campos (las dos FKs más el campo Permitir, que presumiblemente permite varios permisos distintos por cada objeto y usuario, de lo contrario no sería de tipo int, e incluso sería superfluo). En este caso, la FK sí que sería una clave compuesta. Puedes declarar la clave primaria compuesta si quieres, pero si finalmente no vas a tratar la tabla como tabla intermedia sino como una tabla normal, tal vez te resulte más sencillo agregarle un ID de tipo Identity y usar éste como clave primaria.

    • Marcado como respuesta Pedro Ávila martes, 24 de diciembre de 2019 18:22
    martes, 24 de diciembre de 2019 18:17
    Moderador
  • Hola @Alberto

    Me quedo con la tabla ControlAcceso con la siguiente estructura {Id, UsuarioId, ObjetoId, Permitir} Id queda como llave primaria.

    Saludos!


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú

    martes, 24 de diciembre de 2019 18:24
  • hola

    Si a la tabla intermedia de relacion mucho a mucho le vas a poner un dato adicional, como ver el campo "Permitir" (en ControlAcceso) entonces necesitaras mapearla como una entidad diferente que tenga navegacion uno a muchos a las tablas con la cual se relaciona

    Igualmente debo aclararte que un sistema de permisos no se modela de esta forma, sino que se usa el concepto de "Funciones" que son basicamente la funcionalidad que permiten y asignas a un rol

    Por ejemplo en una tabla de funciones creas la funcion de nombre "EliminarArticulos" entonces en el codigo validas si el usuario tiene un rol que incluya esa funcion, si lo tiene entonces permites en el codigo que se elimine un articulo, sino lo tiene no lo permite

    Asi puedes componer Roles agrupando funciones, eso de tener permiso de lectura, actualizar, borrar no es flexible

    Definir roles y funciones que luego en el codigo validas si el usuario tiene la asignacion para poder realizar la operacion o quizas ocultar o mostrar cierta funcionalidad, boton o item de menu

    Pero solo necesitas relaciones simples muchos a muchos para relacionar roles con funciones y los usuarios con estos roles

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    viernes, 27 de diciembre de 2019 16:01
  • Hola @Leandro

    Que te parece este diseño los premisos vendrían hacer las funciones

    Rol: Administrador, Vendedor, etc.

    Permiso: Eliminar, Insertar, etc.

    Objeto: Empresa, Cliente, Proveedor, etc.

    ¿Que debería de corregir?

    Veo que la propiedad permitir esta demás en Objeto, ¿como debería diseñar para poder mostrar y ocultar en el menú?

    Saludos!


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú


    • Editado Pedro Ávila viernes, 27 de diciembre de 2019 20:53
    viernes, 27 de diciembre de 2019 20:27
  • Hola

    Tengo este modelo

    Sería algo como:

    Saludos!


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú

    viernes, 27 de diciembre de 2019 21:46
  • hola

    Si defines funciones, no usas objetos y permisos de los objetos, eso es redundante

    o vas por un camino o vas por otro, no ambos

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    viernes, 27 de diciembre de 2019 22:31
  • Hola

    Rol: System, Administrador, Vendedor. Desde esta ventana a cada rol le voy agregando su control de acceso y sus funciones
    Función: Leer, Insertar, Actualizar, Eliminar
    Ventana: Producto, Cliente, Proveedor, Venta
    Creo una venta rol en la cual le voy agregando las funciones
    Control Acceso: se alimenta de la entidad ventana(son los formularios para administrar quien esta visible)

    Controls Based Security in a Windows Forms Application


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú

    sábado, 28 de diciembre de 2019 15:25
  • hola

    >>Función: Leer, Insertar, Actualizar, Eliminar

    esas no son funciones

    las funciones podria ser: EditarUsuario, EditarArticulos, EliminarProducto, VerPreciosMayoristas, etc

    son funciones dentro de tu aplicacion

    entonces cuando le vas a mostrar el menu, o el boton al usuario para, por ejemplo, permitir eliminar un productos, validas si tiene esa funcion asociada segun su rol y le habilitas el boton o no

    lo mismo los menus, si tienes una pantalla de edicion de usuario, le muestras el item de menu si es que tiene la funcion "EditarUsuario"

    Igual las funciones se pueden complementar porque un usuario puede editar, pero no crear un usuario nuevo, por lo tanto tendras, imaginemos 3 funciones: CrearUsuario, EditarUsuario, EliminarUsuario

    estas 3 funciones las validas para mostrarle los menus o los botones dentro del form de usuarios

    las funciones por lo general son un verbo + un objeto sobre el cual aplica, por eso Crear + Usuario o Nuevo + Prestamo

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Marcado como respuesta Pedro Ávila lunes, 30 de diciembre de 2019 14:26
    lunes, 30 de diciembre de 2019 14:22
  • >>Control Acceso: se alimenta de la entidad ventana(son los formularios para administrar quien esta visible)

    esas tablas de control de acceso puede eliminarlas, no aplican si usas funciones

    la tabla de ventana no funciona, usas funciones no pienses en codigo para la autorizaciones, piensas en definir acciones sobre el sistema

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Marcado como respuesta Pedro Ávila lunes, 30 de diciembre de 2019 14:26
    lunes, 30 de diciembre de 2019 14:24
  • @Leandro

    Veo que voy a tener muchas funciones que ingresar


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú

    lunes, 30 de diciembre de 2019 15:00
  • hola

    >>Veo que voy a tener muchas funciones que ingresar

    las mismas que tendrias si defines con "Ventana" y "ControlAcceso"

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    martes, 31 de diciembre de 2019 5:02