Introducción a las relaciones

En este documento se proporciona una introducción sencilla a la representación de las relaciones en los modelos de objetos y las bases de datos relacionales, incluida la forma en que EF Core se asigna entre los dos.

Relaciones en modelos de objetos

Una relación define cómo se relacionan dos entidades entre sí. Por ejemplo, al modelar publicaciones en un blog, cada publicación está relacionada con el blog en el que se publica, y el blog está relacionado con todas las publicaciones realizadas en él.

En un lenguaje orientado a objetos como C#, el blog y la publicación normalmente se representan mediante dos clases: Blog y Post. Por ejemplo:

public class Blog
{
    public string Name { get; set; }
    public virtual Uri SiteUri { get; set; }
}
public class Post
{
    public string Title { get; set; }
    public string Content { get; set; }
    public DateTime PublishedOn { get; set; }
    public bool Archived { get; set; }
}

En las clases anteriores, no hay nada que indique que Blog y Post están relacionados. Esto se puede incluir en el modelo de objetos agregando una referencia de Post al Blog en el que está publicado:

public class Post
{
    public string Title { get; set; }
    public string Content { get; set; }
    public DateOnly PublishedOn { get; set; }
    public bool Archived { get; set; }

    public Blog Blog { get; set; }
}

Del mismo modo, la dirección opuesta de la misma relación se puede representar como una colección de objetos Post en cada Blog:

public class Blog
{
    public string Name { get; set; }
    public virtual Uri SiteUri { get; set; }

    public ICollection<Post> Posts { get; }
}

Esta conexión de Blog a Post y, a la inversa, de Post a Blog se conoce como una "relación" en EF Core.

Importante

Normalmente, una relación única puede recorrerse en cualquier dirección. En este ejemplo, de Blog a Post mediante la propiedad Blog.Posts y de Post a Blogmediante la propiedad Post.Blog. Se trata de una relación, no dos.

Sugerencia

En EF Core, las propiedades Blog.Posts y Post.Blog se denominan "navegaciones".

Relaciones en bases de datos relacionales

Las bases de datos relacionales representan relaciones mediante claves externas. Por ejemplo, con SQL Server o Azure SQL se pueden usar las tablas siguientes para representar nuestras clases Post y Blog:

CREATE TABLE [Posts] (
    [Id] int NOT NULL IDENTITY,
    [Title] nvarchar(max) NULL,
    [Content] nvarchar(max) NULL,
    [PublishedOn] datetime2 NOT NULL,
    [Archived] bit NOT NULL,
    [BlogId] int NOT NULL,
    CONSTRAINT [PK_Posts] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_Posts_Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blogs] ([Id]) ON DELETE CASCADE);

CREATE TABLE [Blogs] (
    [Id] int NOT NULL IDENTITY,
    [Name] nvarchar(max) NULL,
    [SiteUri] nvarchar(max) NULL,
    CONSTRAINT [PK_Blogs] PRIMARY KEY ([Id]));

En este modelo relacional, las tablas Posts y Blogs tienen una columna "clave principal". El valor de la clave principal identifica de forma única cada publicación o blog. Además, a la tabla Posts se le asigna una columna "clave externa". En la tabla Blogs, la columna de clave principal Id hace referencia a la columna de clave externa BlogId de la tabla Posts. Esta columna está "restringida", de modo que cualquier valor de la columna BlogId de Postsdebe coincidir con un valor de la columna Id de Blogs. Esta coincidencia determina con qué blog está relacionada cada publicación. Por ejemplo, si el valor de BlogId en una fila de la tabla Posts es 7, la publicación representada por esa fila se publica en el blog con la clave principal 7.

Asignación de relaciones en EF Core

La asignación de relaciones de EF Core consiste en asignar la representación de clave principal o clave externa usada en una base de datos relacional a las referencias entre los objetos usados en un modelo de objetos.

En el sentido más básico, esto implica lo siguiente:

  • Agregar una propiedad de clave principal a cada tipo de entidad.
  • Agregar una propiedad de clave externa a un tipo de entidad.
  • Asociar las referencias entre los tipos de entidad con las claves principales y externas para formar una única configuración de relación.

Una vez realizada esta asignación, EF modifica los valores de las claves externas según sea necesario cuando cambian las referencias entre los objetos y modifica las referencias entre los objetos según sea necesario cuando cambian los valores de las claves externas.

Nota:

Las claves principales no solo se usan para la asignación de relaciones. Consulte Claves para obtener más información.

Por ejemplo, los tipos de entidad mostrados anteriormente se pueden actualizar con las propiedades de clave principal y externa:

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual Uri SiteUri { get; set; }

    public ICollection<Post> Posts { get; }
}
public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public DateTime PublishedOn { get; set; }
    public bool Archived { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

Sugerencia

Las propiedades de clave principal y externa no necesitan ser propiedades visibles públicamente del tipo de entidad. Pero, incluso cuando las propiedades están ocultas, es importante reconocer que todavía existen en el modelo de EF.

De este modo, la propiedad de clave principal de Blog (Blog.Id) y la propiedad de clave externa de Post (Post.BlogId) se pueden asociar con las referencias ("navegaciones") entre los tipos de entidad (Blog.Posts y Post.Blog). EF hace esto automáticamente al crear una relación simple como esta, pero también se puede especificar explícitamente al reemplazar el método OnModelCreating de DbContext. Por ejemplo:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .HasMany(e => e.Posts)
        .WithOne(e => e.Blog)
        .HasForeignKey(e => e.BlogId)
        .HasPrincipalKey(e => e.Id);
}

Ahora todas estas propiedades se comportarán de forma coherente como una representación de una única relación entre Blog y Post.

Obtén más información

EF admite muchos tipos diferentes de relaciones, con muchas maneras distintas de representar y configurar estas relaciones. Para ver ejemplos de diferentes tipos de relaciones, consulte:

Si no está familiarizado con EF, se recomienda probar los ejemplos de los artículos anteriores para conocer cómo funcionan las relaciones.

Para profundizar más en las propiedades de los tipos de entidad implicados en la asignación de relaciones, consulte:

Los modelos de EF se compilan mediante una combinación de tres mecanismos: convenciones, atributos de asignación y la API del generador de modelos. La mayoría de los ejemplos muestran la API de generación de modelos. Para obtener más información sobre otras opciones, consulte:

Importante

La API de generación de modelos es el único origen de verdad para el modelo de EF, por lo que siempre tiene prioridad sobre la configuración descubierta por las convenciones o especificada por los atributos de asignación. También es el único mecanismo con fidelidad completa para configurar todos los aspectos del modelo de EF.

Otros temas relacionados con las relaciones son:

  • Eliminación en cascada, que describe cómo se pueden eliminar automáticamente las entidades relacionadas cuando se llama a SaveChanges o SaveChangesAsync.
  • Tipos de entidad en propiedad, los cuales usan un tipo especial de relación de "propiedad" que implica una conexión entre los dos tipos más fuerte que en las relaciones "normales" que se describen aquí. Muchos de los conceptos que se describen aquí para las relaciones normales se aplican también a las relaciones de propiedad. Pero, las relaciones de propiedad también tienen sus propios comportamientos especiales.

Sugerencia

Consulte el glosario de términos para relaciones según sea necesario al leer la documentación para comprender mejor la terminología usada.

Uso de relaciones

Las relaciones definidas en el modelo se pueden usar de varias maneras. Por ejemplo: