none
EFCore 3.1 Relación Many to Many RRS feed

  • Pregunta

  • Hola 

    Trabajo con EFCore 3.1 estoy implementando una relación muchos a muchos, estoy implementando una relación many to many entre Productos y Colores.

    Producto

    public class Producto
        {
            public int ProductoId { get; set; }
            public ProductoType TipoProducto { get; set; }
            public string Codigo { get; set; } //13 dígitos
            public string CodigoBarra { get; set; } //15 dígitos
            public string Nombre { get; set; } 
            public int CategoriaId { get; set; }
            public int SubCategoriaId { get; set; }
            public int? MarcaId { get; set; }
            public int MonedaId { get; set; }
            public int MedidaId { get; set; }
            public int PresentacionId { get; set; }
            public int? LaboratorioId { get; set; }
            public DateTime? FechaVencimiento { get; set; }
            public decimal PrecioCompra { get; set; }
            public string Lote { get; set; }
            public IncluyeImpuesto IncluyeImpuesto { get; set; }
            public ProductoStatus Estado { get; set; }
            public bool CalculoImportePorRangos { get; set; }
    
            public virtual Categoria Categoria { get; set; }
            public virtual SubCategoria SubCategoria { get; set; }
            public virtual Marca Marca { get; set; }
            public virtual Moneda Moneda { get; set; }
            public virtual Medida Medida { get; set; }
            public virtual Presentacion Presentacion { get; set; }
            public virtual Laboratorio Laboratorio { get; set; }
    
            public virtual ICollection<Colour> Colores { get; set; } 
            
            public virtual ICollection<ProductoColor> ProductoColores { get; set; }
        }

    En EF6 se pone la lista de B en A y la de A en B, pero en EFCore ya se usa.

    Color

    public class Colour
        {
            public int ColorId { get; set; }
            public string Nombre { get; set; }
    
            public virtual ICollection<Producto> Productos { get; set; }
    
            public virtual ICollection<ProductoColor> ProductoColores { get; set; }
        }

    Debería eliminar la lista Productos en Colour y la lista Colores de Producto por que según la documentación se implementa de otra manera poniendo una lista que representa la relación de la tabla intermedia. La cual la tengo.

    public class ProductoColor
        {
            public int ProductoId { get; set; }
            public int ColorId { get; set; }
    
            public virtual Producto Producto { get; set; }
            public virtual Colour Colour { get; set; }
        }

    .....

    modelBuilder.Entity<ProductoColor>()
                    .HasKey(c => new { c.ProductoId, c.ColorId });
    
                modelBuilder.Entity<ProductoColor>()
                    .HasOne(pc => pc.Producto)
                    .WithMany(p => p.ProductoColores)
                    .HasForeignKey(pc => pc.ProductoId);
    
                modelBuilder.Entity<ProductoColor>()
                    .HasOne(pc => pc.Colour)
                    .WithMany(c => c.ProductoColores)
                    .HasForeignKey(pc => pc.ColorId);

    Me da este error al hacer la migración

    Unable to determine the relationship represented by navigation property 'Colour.Productos' of type 'ICollection<Producto>'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

    ¿No hay manera de dejar esa lista?

    Saludos!


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

    miércoles, 29 de julio de 2020 23:35

Respuestas

  • hola

    Porque dejas la propiedad

       public virtual ICollection<Colour> Colores { get; set; }

    en Producto ? eso ya no va

    Sino lo defines como  [NotMapped] EF intentara aplicar convenciones en el mapping y tedras problemas

    Tambien elimina la propiedad

       public virtual ICollection<Producto> Productos { get; set; }

    en Colour

    Many-to-many

    Ademas que es Colour? esta en Frances o solo se agrego una U de mas

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Marcado como respuesta Pedro Ávila jueves, 30 de julio de 2020 14:33
    jueves, 30 de julio de 2020 4:01
  • hola

    >>Yo le puse la u por Color es una palabra reservada del framework

    No veo que sea una palabra reservada

    Palabras clave de C#

    del lenguaje

    Use the long reserved word as a variable name in C#

    Si es una estructura que se usa junto a la funcionalidad de dibujo, pero si en el contexto de negocio no agregas esos using a los namespaces no tendras problema

    >>Me va tocar modificar los métodos que trabajo las relaciones muchos a muchos

    me temo que si

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Marcado como respuesta Pedro Ávila jueves, 30 de julio de 2020 14:34
    jueves, 30 de julio de 2020 14:29

Todas las respuestas

  • Hola Pedro Ávila,

    Hay varias soluciones. Te dejo este enlace en el que le dan a una persona con una duda muy similar a la tuya una respuesta bastante completa. Espero que te sea de ayuda y quedo pendiente de cualquier actualización. Gracias por levantar tu consulta en los foros de msdn.

     

    Saludos cordiales

    Gabriel Castro

     ____________________________ 

    Por favor recuerde "Marcar como respuesta" las respuestas que hayan resuelto su problema, es una forma común de reconocer a aquellos que han ayudado, y hace que sea más fácil para los otros visitantes encontrar la solución más tarde.  


    jueves, 30 de julio de 2020 0:55
    Moderador
  • hola

    Porque dejas la propiedad

       public virtual ICollection<Colour> Colores { get; set; }

    en Producto ? eso ya no va

    Sino lo defines como  [NotMapped] EF intentara aplicar convenciones en el mapping y tedras problemas

    Tambien elimina la propiedad

       public virtual ICollection<Producto> Productos { get; set; }

    en Colour

    Many-to-many

    Ademas que es Colour? esta en Frances o solo se agrego una U de mas

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Marcado como respuesta Pedro Ávila jueves, 30 de julio de 2020 14:33
    jueves, 30 de julio de 2020 4:01
  • Hola @Leandro

    Voy a eliminar las listas que mencionas veo que EFCore se hace de otra manera respecto a EF6

    Ademas que es Colour? esta en Frances o solo se agrego una U de mas

    Yo le puse la u por Color es una palabra reservada del framework y para no tener problemas le agregue una u

    Me va tocar modificar los métodos que trabajo las relaciones muchos a muchos ejm. 

    public async Task AsignarColores(Producto producto, List<Colour> colores)
            {
                using (var context = new BusinessContext())
                {
                    context.Entry(producto).State = EntityState.Unchanged;
    
                    if (producto.Colores == null)
                        producto.Colores = new List<Colour>();
    
                    await Task.Run(() =>
                    {
                        //Recorremos cada Modelo que se quiera asociar
                        colores.ForEach(x =>
                        {
                            //El Modelo tampoco debe recibir cambios
                            context.Entry(x).State = EntityState.Unchanged;
                            //Asociamos a la coleción de Modelo del Proveedor el nuevo item
                            //Este si recibira cambios
                            producto.Colores.Add(x);
                            context.SaveChanges();
                        });
                    });
                }
            }

    Saludos!


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


    jueves, 30 de julio de 2020 10:49
  • hola

    >>Yo le puse la u por Color es una palabra reservada del framework

    No veo que sea una palabra reservada

    Palabras clave de C#

    del lenguaje

    Use the long reserved word as a variable name in C#

    Si es una estructura que se usa junto a la funcionalidad de dibujo, pero si en el contexto de negocio no agregas esos using a los namespaces no tendras problema

    >>Me va tocar modificar los métodos que trabajo las relaciones muchos a muchos

    me temo que si

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Marcado como respuesta Pedro Ávila jueves, 30 de julio de 2020 14:34
    jueves, 30 de julio de 2020 14:29