entity-framework-relaciones-uno-a-muchos

Relaciones uno a muchos en Entity Framework

  • 4 min

Una relación uno a muchos (1) ocurre cuando una entidad A puede tener muchas instancias de una entidad B, pero cada instancia de B está relacionada con una sola A.

En otras palabras, un registro de una tabla puede estar relacionado con varios registros en otra tabla, pero un registro de la segunda tabla solo puede estar asociado a un registro de la primera tabla.

Este es el tipo de relación más común en las bases de datos

Vamos a modelar un sistema donde:

  • Un Blog puede tener muchos Posts.
  • Cada Post pertenece a un solo Blog.
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    
    // Propiedad de navegación (1 → N)
    public ICollection<Post> Posts { get; set; } = new List<Post>();
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    
    // Clave foránea implícita (BlogId)
    public int BlogId { get; set; }
    
    // Propiedad de navegación (N → 1)
    public Blog Blog { get; set; }
}

Configurar la relación

Estructura de la base de datos generada

Al aplicar una migración, EF crea las tablas:

CREATE TABLE Blogs (
    BlogId INT PRIMARY KEY IDENTITY,
    Url NVARCHAR(MAX)
);

CREATE TABLE Posts (
    PostId INT PRIMARY KEY IDENTITY,
    Title NVARCHAR(MAX),
    Content NVARCHAR(MAX),
    BlogId INT NOT NULL,
    FOREIGN KEY (BlogId) REFERENCES Blogs(BlogId)
);

BlogId en Posts es una clave foránea no única (permite múltiples posts por blog).

Configuraciones avanzadas

Aparte de las relaciones básicas, Entity Framework permite configurar de manera avanzada aspectos de las relaciones entre entidades. Esto incluye:

Relación con eliminación en cascada

Cuando una entidad relacionada se elimina, la eliminación en cascada asegura que todas las entidades relacionadas se eliminen también.

modelBuilder.Entity<Libro>()
    .HasOne(l => l.Autor)
    .WithMany(a => a.Libros)
    .OnDelete(DeleteBehavior.Cascade);

Relación de sólo lectura

En algunas situaciones, puede que no quieras permitir que se modifique una relación en una entidad.

modelBuilder.Entity<Libro>()
    .HasOne(l => l.Autor)
    .WithMany(a => a.Libros)
    .OnDelete(DeleteBehavior.Restrict);

Relaciones opcionales

Algunas relaciones son opcionales, lo que significa que una entidad puede no tener una relación con la otra.

modelBuilder.Entity<Libro>()
    .HasOne(l => l.Autor)
    .WithMany(a => a.Libros)
    .IsRequired(false);  // Relación opcional

Ejemplos practicos