none
Borrar relación muchos a muchos RRS feed

  • Pregunta

  • Hola como va a todos tengo un formulario en donde establezco relación muchos a muchos tengo  tablas Empleados,Turnos y RelacionEmpleadosTurnos que es la intermedia entre las 2 primeras tablas creo la relación de esta forma

    if ((bsEmpleados.Current != null) && (bsTurnos.Current != null))
                {
                    Empleados ep = (Empleados)bsEmpleados.Current;
                    Turnos tu = (Turnos)bsTurnos.Current;
                    RelacionEmpleadoTurnos assoc = new RelacionEmpleadoTurnos();
                    assoc.Empleados = ep;
                    assoc.Turnos = tu;
                    
                    ep.RelacionEmpleadoTurnos.Add(assoc);
                    tu.RelacionEmpleadoTurnos.Add(assoc);
                    dbcontext.SaveChanges();
                }

    Hasta aquí todo bien mi pregunta es como debería borrar esa relación en los 3 casos que se presentarían 1- solo borrar el registro en la tabla RelacionEmpleadosTurnos 2- En caso de que se elimine el registro empleado borrar toda la relación y 3- En caso de que se elimine el registro turno borrar toda la relacion y este es mi modelo edmx

    Desde ya gracias

    sábado, 17 de septiembre de 2016 22:10

Respuestas

  • EnzoTuc40,

    La representación que haces de una correspondencia N:M (many to many) es incorrecta, la entidad intermedia (RelacionEmpleadosTurnos) debería contener únicamente las referencias de las entidades relacionadas componiendo con ellas una clave primaria, el atributo 'Id' es innecesario. Para que quede claro lo que te comento te comparto un enlace Many to Many Relationship : a step by step View Model approach, donde ademas se muestra como implementar este tipo de relaciones considerando el acercamiento EF ModelFirst/DataBaseFirst.

    Respecto a tu pregunta de como borrar filas de las tablas que muestras:

    1. Tabla 'RelaciónEmpleadosTurnos': es una operación de DELETE sobre la tabla conteniendo una referencia basada en los valores de los dos atributos o de uno de los dos.
    2. Tablas 'Turnos' y 'Empleados': podrías implementar (a nivel de base de datos) reglas de eliminación en cascada, de tal forma que al eliminar una fila de cualquier de las dos tablas se eliminará automáticamente las filas relacionadas (en la tabla intermedia).


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta EnzoTuc40 domingo, 18 de septiembre de 2016 15:51
    sábado, 17 de septiembre de 2016 22:47

Todas las respuestas

  • EnzoTuc40,

    La representación que haces de una correspondencia N:M (many to many) es incorrecta, la entidad intermedia (RelacionEmpleadosTurnos) debería contener únicamente las referencias de las entidades relacionadas componiendo con ellas una clave primaria, el atributo 'Id' es innecesario. Para que quede claro lo que te comento te comparto un enlace Many to Many Relationship : a step by step View Model approach, donde ademas se muestra como implementar este tipo de relaciones considerando el acercamiento EF ModelFirst/DataBaseFirst.

    Respecto a tu pregunta de como borrar filas de las tablas que muestras:

    1. Tabla 'RelaciónEmpleadosTurnos': es una operación de DELETE sobre la tabla conteniendo una referencia basada en los valores de los dos atributos o de uno de los dos.
    2. Tablas 'Turnos' y 'Empleados': podrías implementar (a nivel de base de datos) reglas de eliminación en cascada, de tal forma que al eliminar una fila de cualquier de las dos tablas se eliminará automáticamente las filas relacionadas (en la tabla intermedia).


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta EnzoTuc40 domingo, 18 de septiembre de 2016 15:51
    sábado, 17 de septiembre de 2016 22:47
  • Hola @EnzoTuc40

    Hola como va a todos tengo un formulario en donde establezco relación muchos a muchos

    Las relaciones se establecen en el modelo de datos, o en la base de datos

    tengo  tablas Empleados,Turnos y RelacionEmpleadosTurnos que es la intermedia entre las 2 primeras tablas creo la relación de esta forma

    ¿En que enfoque de Entity Framework estas trabajando?

    Code First, es un enfoque mas de Entity Framework que permite crear una base de datos a partir de código(C#, VB.NET), por defecto se utiliza el nombre de nuestras clases y correspondientes propiedades para crear nombres de tablas y campos.

    Model First, le da la posibilidad de diseñar toda la lógica del negocio, le permite crear un modelo nuevo mediante Entity Framework Designer y después genera un esquema de la base de datos a partir del modelo.

    Database First, el modelo conceptual se crea a partir de una base de datos existente, el cual se almacena en una archivo .edmx y este se podrá ver y editar en un diseñador, para actualizar nuevos cambios que surjan en nuestra base de datos.

    Si esta trabajando con Database Firts, tu base de datos debería tener este tipo de relación Many to Many

    El atributo Id de tu tabla intermedia esta demás, eliminala.

    Si estas trabajando con el enfoque Code First, deberías hacer algo como esto:

    public ProductoMap()
            {
                ToTable("Productos");
                HasKey(c => c.ProductoId);
                Property(c => c.ProductoId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    
                Property(c => c.ProductoId).HasColumnOrder(0);
    
                HasRequired(c => c.Categoria).WithMany(c => c.Productos).HasForeignKey(c => c.CategoriaId)
                    .WillCascadeOnDelete(false);
                Property(c => c.CategoriaId).IsRequired().HasColumnOrder(1);
    
                HasRequired(c => c.Linea).WithMany(c => c.Productos).HasForeignKey(c => c.LineaId)
                    .WillCascadeOnDelete(false);
                Property(c => c.LineaId).IsRequired().HasColumnOrder(2);
    
                HasRequired(c => c.Modelo).WithMany(c => c.Productos).HasForeignKey(c => c.ModeloId)
                    .WillCascadeOnDelete(false);
                Property(c => c.ModeloId).IsRequired().HasColumnOrder(3);
    
                HasRequired(c => c.Marca).WithMany(c => c.Productos).HasForeignKey(c => c.MarcaId)
                    .WillCascadeOnDelete(false);
                Property(c => c.MarcaId).IsRequired().HasColumnOrder(4);
    
                Property(c => c.CodigoBarra).HasMaxLength(8).HasColumnOrder(5);
    
                Property(c => c.Nombre).IsRequired().HasMaxLength(100).HasColumnOrder(6);
                Property(c => c.Imagen).HasColumnOrder(7);
    
                HasMany(c => c.Proveedores)
                    .WithMany(c => c.Productos)
                    .Map(mc =>
                    {
                        mc.MapLeftKey("ProductoId");
                        mc.MapRightKey("ProveedorId");
                        mc.ToTable("ProductoProveedor");
                    });
            }

    Espero te sea de utilidad.


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



    • Editado Pedro Ávila domingo, 18 de septiembre de 2016 0:49 ...
    domingo, 18 de septiembre de 2016 0:21
  • No es incorrecta.

    Si coloca un ID en la tabla intermedia, es pq en el modelo muy probablemente se requiera q sea clave foránea de otra tabla, es mejor bajar un PK que un PK compuesto.

    Al realizar la operación de DELETE cómo garantizas consistencia de datos si hay un corte de comunicación, asumo que el DELETE q propones es a través de de un sql directo??

    En cuanto a reglas de eliminación en CASCADA si trabajas a un nivel de sistema bancario, esto NO SE ACOSTUMBRA por temas de seguridad.

    De igual forma podría ser que el cliente quiera una eliminación tan solo lógica.


    bgva

    jueves, 20 de julio de 2017 21:36