lunes, 24 de febrero de 2014

[EntityFramework] Configurando una relación de uno a muchos en Code First

En el artículo anterior vimos cómo configurar una relación de uno a uno en Code First usando Data Annotations y Fluent Api, en esta ocasión vamos a ver cómo configurar una relación de uno a muchos usando las mismas entidades de dominio Producto y Categoria.

Relación de uno a muchos mediante Data Annotations:

Nuestra entidad Producto será de la siguiente forma:

    [Table("Productos")]
    public class Producto
    {
        [Key]
        public int Codigo { getset; }
 
        [Required]
        [Column("Nombre", TypeName = "varchar", Order = 2)]
        public string Nombre { getset; }
 
        [MaxLength(100), MinLength(10)]
        public string Descripcion { getset; }
 
        [NotMapped]
        public string CodigoIso { getset; }
 
        [ForeignKey("Categoria")]
        public int IdCategoria { getset; }
 
        public virtual Categoria Categoria { getset; }
    }

Cómo ven agregamos IdCategoria y especificamos que se trata de la clave foránea con respecto a la entidad categoria, de igual forma agregamos la propiedad Categoria de tipo Categoria que representa la relación, y a continuación en nuestra entidad Categoria agregaremos una colección de tipo Producto para indicar que una categoría puede tener uno o muchos productos:

    public class Categoria
    {
        [Key]
        public int Id { getset; }
 
        [MaxLength(100)]
        public string Nombre { getset; }
 
        [MaxLength(200)]
        public string Descripcion { getset; }
 
        [Required]
        public virtual ICollection<Producto> Producto { getset; }
    }

Y con esto tenemos configurada nuestra relación de una a muchos entre Productos y Categorías a través de Data Annotations, ahora para probar la configuración podemos crear una app de consola y copiar el siguiente código en la clase program:

    class Program
    {
        static void Main(string[] args)
        {
            var categoria = new Categoria { Id = 1, Nombre = "Lacteos", Descripcion = "Productos lacteos" };
            var producto = new Producto { Codigo = 1, Nombre = "Leche", Descripcion = "Producto Lacteo", Categoria = categoria };
            var producto2 = new Producto { Codigo = 2, Nombre = "Queso", Descripcion = "Producto Lacteo", Categoria = categoria };
            using (var contexto = new Context())
            {
                contexto.Productos.Add(producto);
                contexto.Productos.Add(producto2);
                contexto.SaveChanges();
            }
        }
    }

Relación de uno a muchos mediante Fluent Api:

Ahora vamos a configurar la relación de uno a muchos entre Productos y Categorías, pero esta vez vamos a usar Fluent Api para lograrlo:

    public class Context : DbContext
    {
        public Context() : base("Productos")
        {
            
        }
 
        public DbSet<Producto> Productos { getset; }
 
        public DbSet<Categoria> Categorias { getset; }
 
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            // Aquí haremos nuestras configuraciones con Fluent API.
 
            modelBuilder.Configurations.Add(new ProductoMappings());
 
            modelBuilder.Entity<Producto>()
                .HasRequired<Categoria>(c => c.Categoria)
                .WithMany(c => c.Productos)
                .HasForeignKey(c => c.IdCategoria);
 
            base.OnModelCreating(modelBuilder);
        }
    }

Cómo vemos en el método OnModelCreating especificamos la relación a través de Fluent Api, dónde indicamos la relación partiendo la entidad Producto e indicamos el WithMany con Categoría.

Y bueno amigos, eso es todo, espero les sea de utilidad y de interés este post acerca de relación uno a muchos en Entity Framework code First, en el próximo artículo observaremos cómo configurar una relación de muchos a muchos, para terminar con el tema de relaciones y seguir con otros temas.

Saludos y buena suerte!

6 comentarios:

  1. Hola... una consulta como harias para recuperar las categorias de un producto??? y la categorias que no estan asociadas a un producto??

    ResponderEliminar
    Respuestas
    1. Hola amigo, para recuperar todas las categorías asociadas a un producto, puedes usar Producto.Include("Categorias"), como explico en este artículo: http://www.eltavo.net/2014/04/entityframework-interactuando-con.html
      y para recuperar todas aquellas categorias que no estén asociadas a un producto podrías hacer un query de los productos con include, y en el where especificas que solo te traiga las que su propiedad categorias.Count sea mayor a 0.

      saludos!

      Eliminar
    2. * sea igual a cero, perdón!

      Eliminar
  2. Respuestas
    1. Hola Reghis, que bueno que te resultó útil la explicación, gracias por comentar, saludos!

      Eliminar
  3. Y como seria una relacion de uno a (cero o uno)

    ResponderEliminar