RelationshipsRelationships

Une relation définit comment deux entités sont liés entre eux.A relationship defines how two entities relate to each other. Dans une base de données relationnelle, il est représenté par une contrainte de clé étrangère.In a relational database, this is represented by a foreign key constraint.

Note

La plupart des exemples dans cet article utilisent une relation un-à-plusieurs pour illustrer les concepts.Most of the samples in this article use a one-to-many relationship to demonstrate concepts. Pour obtenir des exemples de relations un à un et plusieurs-à-plusieurs, consultez le autres modèles de relation section à la fin de l’article.For examples of one-to-one and many-to-many relationships see the Other Relationship Patterns section at the end of the article.

Définition des termesDefinition of Terms

Il existe un nombre de termes utilisés pour décrire des relationsThere are a number of terms used to describe relationships

  • Entité dépendante : cela est l’entité qui contient les propriétés de clés étrangères.Dependent entity: This is the entity that contains the foreign key property(s). Parfois comme enfant de la relation.Sometimes referred to as the 'child' of the relationship.

  • Entité principale : cela est l’entité qui contient les propriétés de clés primaire/remplacement.Principal entity: This is the entity that contains the primary/alternate key property(s). Parfois appelée « parent » de la relation.Sometimes referred to as the 'parent' of the relationship.

  • Clé étrangère : les propriétés de l’entité dépendante qui est utilisée pour stocker les valeurs de la propriété de clé principale associée à l’entité.Foreign key: The property(s) in the dependent entity that is used to store the values of the principal key property that the entity is related to.

  • Clé principale : la propriété qui identifie de façon unique l’entité principale.Principal key: The property(s) that uniquely identifies the principal entity. Cela peut être la clé primaire ou une autre clé.This may be the primary key or an alternate key.

  • Propriété de navigation : une propriété définie sur l’entité principale et/ou dépendante qui contient une ou plusieurs références aux ou les entités connexes.Navigation property: A property defined on the principal and/or dependent entity that contains a reference(s) to the related entity(s).

    • Propriété de navigation de collection : une propriété de navigation qui contient des références à nombreuses entités connexes.Collection navigation property: A navigation property that contains references to many related entities.

    • Référence de propriété de navigation : une propriété de navigation qui conserve une référence à une entité connexe unique.Reference navigation property: A navigation property that holds a reference to a single related entity.

    • Propriété de navigation inversée : lorsque vous présentez une propriété de navigation particulier, ce terme fait référence à la propriété de navigation à l’autre extrémité de la relation.Inverse navigation property: When discussing a particular navigation property, this term refers to the navigation property on the other end of the relationship.

Le code suivant montre une relation un-à-plusieurs entre Blog etPostThe following code listing shows a one-to-many relationship between Blog and Post

  • Postest de l’entité dépendantePost is the dependent entity

  • Blogest de l’entité principaleBlog is the principal entity

  • Post.BlogIdest la clé étrangèrePost.BlogId is the foreign key

  • Blog.BlogIdest la clé principale (dans ce cas il est une clé primaire plutôt que d’une autre clé)Blog.BlogId is the principal key (in this case it is a primary key rather than an alternate key)

  • Post.Blogest une propriété de navigation de référencePost.Blog is a reference navigation property

  • Blog.Postsest une propriété de navigation de collectionBlog.Posts is a collection navigation property

  • Post.Blogla propriété de navigation inversée de Blog.Posts (et vice versa)Post.Blog is the inverse navigation property of Blog.Posts (and vice versa)

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

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

ConventionsConventions

Par convention, une relation sera créée lors d’une propriété de navigation détectée sur un type.By convention, a relationship will be created when there is a navigation property discovered on a type. Une propriété est considérée comme une propriété de navigation si le type vers lequel elle pointe ne peut pas être mappé en tant que type scalaire par le fournisseur actuel de la base de données.A property is considered a navigation property if the type it points to can not be mapped as a scalar type by the current database provider.

Note

Les relations qui sont découverts par convention ciblera toujours la clé primaire de l’entité principale.Relationships that are discovered by convention will always target the primary key of the principal entity. Pour cibler une autre clé, une configuration supplémentaire doit être effectuée à l’aide de l’API Fluent.To target an alternate key, additional configuration must be performed using the Fluent API.

Relations entièrement définiesFully Defined Relationships

Le modèle le plus courant pour les relations est d’avoir des propriétés de navigation définies sur les deux extrémités de la relation et une propriété de clé étrangère définie dans la classe d’entité dépendante.The most common pattern for relationships is to have navigation properties defined on both ends of the relationship and a foreign key property defined in the dependent entity class.

  • Si une paire de propriétés de navigation se trouve entre deux types, ils seront configurés en tant que propriétés de navigation inverse de la même relation.If a pair of navigation properties is found between two types, then they will be configured as inverse navigation properties of the same relationship.

  • Si l’entité dépendante contient une propriété nommée <primary key property name>, <navigation property name><primary key property name>, ou <principal entity name><primary key property name> , puis il sera configuré en tant que la clé étrangère.If the dependent entity contains a property named <primary key property name>, <navigation property name><primary key property name>, or <principal entity name><primary key property name> then it will be configured as the foreign key.

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

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

Avertissement

S’il existe plusieurs propriétés de navigation définies entre deux types (autrement dit, plusieurs paires distinctes de navigations qui pointent vers l’autre), alors aucune relation ne sera créée par convention, et vous devez les configurer manuellement pour identifier la propriétés de navigation par deux.If there are multiple navigation properties defined between two types (i.e. more than one distinct pair of navigations that point to each other), then no relationships will be created by convention and you will need to manually configure them to identify how the navigation properties pair up.

Aucune propriété de clé étrangèreNo Foreign Key Property

S’il est recommandé d’avoir une propriété de clé étrangère définie dans la classe d’entité dépendante, il n’est pas nécessaire.While it is recommended to have a foreign key property defined in the dependent entity class, it is not required. Si aucune propriété de clé étrangère n’est trouvée, une propriété de clé étrangère de clichés instantanés est introduite avec le nom <navigation property name><principal key property name> (consultez occulter les propriétés pour plus d’informations).If no foreign key property is found, a shadow foreign key property will be introduced with the name <navigation property name><principal key property name> (see Shadow Properties for more information).

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog { get; set; }
}

Propriété de NavigationSingle Navigation Property

Notamment qu’une propriété de navigation (aucune navigation inverse et aucune propriété de clé étrangère) est suffisante pour permettre une relation définie par convention.Including just one navigation property (no inverse navigation, and no foreign key property) is enough to have a relationship defined by convention. Vous pouvez également avoir une propriété de navigation et une propriété de clé étrangère.You can also have a single navigation property and a foreign key property.

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
}

Suppression en cascadeCascade Delete

Par convention, la suppression en cascade est définie sur Cascade pour les relations requises et ClientSetNull pour les relations facultatif.By convention, cascade delete will be set to Cascade for required relationships and ClientSetNull for optional relationships. Cascade signifie entités dépendantes sont également supprimées.Cascade means dependent entities are also deleted. ClientSetNull signifie que les entités dépendantes ne sont pas chargées en mémoire reste inchangée et doit être supprimés manuellement ou mis à jour pour pointer vers une entité principale valide.ClientSetNull means that dependent entities that are not loaded into memory will remain unchanged and must be manually deleted, or updated to point to a valid principal entity. Pour les entités qui sont chargées en mémoire, EF Core tente de définir les propriétés de clé étrangères sur null.For entities that are loaded into memory, EF Core will attempt to set the foreign key properties to null.

Consultez le relations obligatoires et facultatifs section de la différence entre les relations requises et facultatives.See the Required and Optional Relationships section for the difference between required and optional relationships.

Consultez suppression en Cascade pour plus d’informations sur les différents comportements et les valeurs par défaut utilisés par la convention de suppression.See Cascade Delete for more details about the different delete behaviors and the defaults used by convention.

Annotations de donnéesData Annotations

Il existe deux des annotations de données qui peuvent être utilisées pour configurer des relations, [ForeignKey] et [InverseProperty].There are two data annotations that can be used to configure relationships, [ForeignKey] and [InverseProperty].

[ForeignKey][ForeignKey]

Vous pouvez utiliser les Annotations de données pour configurer la propriété doit être utilisée comme propriété de clé étrangère pour une relation donnée.You can use the Data Annotations to configure which property should be used as the foreign key property for a given relationship. Cela est généralement le cas lorsque la propriété de clé étrangère n’est pas découvert par convention.This is typically done when the foreign key property is not discovered by convention.

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogForeignKey { get; set; }

    [ForeignKey("BlogForeignKey")]
    public Blog Blog { get; set; }
}

Conseil

Le [ForeignKey] annotation peut être placée sur une propriété de navigation dans la relation.The [ForeignKey] annotation can be placed on either navigation property in the relationship. Il n’a pas besoin de passer la propriété de navigation dans la classe d’entité dépendante.It does not need to go on the navigation property in the dependent entity class.

[InverseProperty][InverseProperty]

Vous pouvez utiliser les Annotations de données pour configurer la façon dont les propriétés de navigation sur les entités principales et dépendantes par deux.You can use the Data Annotations to configure how navigation properties on the dependent and principal entities pair up. Cela est généralement le cas lorsqu’il y a plus d’une paire de propriétés de navigation entre les deux types d’entité.This is typically done when there is more than one pair of navigation properties between two entity types.

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int AuthorUserId { get; set; }
    public User Author { get; set; }

    public int ContributorUserId { get; set; }
    public User Contributor { get; set; }
}

public class User
{
    public string UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    [InverseProperty("Author")]
    public List<Post> AuthoredPosts { get; set; }

    [InverseProperty("Contributor")]
    public List<Post> ContributedToPosts { get; set; }
}

API FluentFluent API

Pour configurer une relation dans l’API Fluent, commencez par identifier les propriétés de navigation qui composent la relation.To configure a relationship in the Fluent API, you start by identifying the navigation properties that make up the relationship. HasOneou HasMany identifie la propriété de navigation sur le type d’entité vous sont à partir de la configuration.HasOne or HasMany identifies the navigation property on the entity type you are beginning the configuration on. Vous liez ensuite un appel à WithOne ou WithMany pour identifier le volet de navigation inverse.You then chain a call to WithOne or WithMany to identify the inverse navigation. HasOne/WithOnesont utilisés pour les propriétés de navigation de référence et HasMany / WithMany sont utilisés pour les propriétés de navigation de collection.HasOne/WithOne are used for reference navigation properties and HasMany/WithMany are used for collection navigation properties.

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts);
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog { get; set; }
}

Propriété de NavigationSingle Navigation Property

Si vous avez uniquement une propriété de navigation, les surcharges sans paramètre de WithOne et WithMany.If you only have one navigation property then there are parameterless overloads of WithOne and WithMany. Cela indique qu’il le concept est une référence ou une collection à l’autre extrémité de la relation, mais il n’existe aucune propriété de navigation incluse dans la classe d’entité.This indicates that there is conceptually a reference or collection on the other end of the relationship, but there is no navigation property included in the entity class.

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .HasMany(b => b.Posts)
            .WithOne();
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
}

Clé étrangèreForeign Key

Vous pouvez utiliser l’API Fluent pour configurer la propriété doit être utilisée comme propriété de clé étrangère pour une relation donnée.You can use the Fluent API to configure which property should be used as the foreign key property for a given relationship.

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts)
            .HasForeignKey(p => p.BlogForeignKey);
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

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

Le code suivant montre comment configurer une clé étrangère composite.The following code listing shows how to configure a composite foreign key.

class MyContext : DbContext
{
    public DbSet<Car> Cars { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Car>()
            .HasKey(c => new { c.State, c.LicensePlate });

        modelBuilder.Entity<RecordOfSale>()
            .HasOne(s => s.Car)
            .WithMany(c => c.SaleHistory)
            .HasForeignKey(s => new { s.CarState, s.CarLicensePlate });
    }
}

public class Car
{
    public string State { get; set; }
    public string LicensePlate { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }

    public List<RecordOfSale> SaleHistory { get; set; }
}

public class RecordOfSale
{
    public int RecordOfSaleId { get; set; }
    public DateTime DateSold { get; set; }
    public decimal Price { get; set; }

    public string CarState { get; set; }
    public string CarLicensePlate { get; set; }
    public Car Car { get; set; }
}

Vous pouvez utiliser la surcharge de chaîne de HasForeignKey(...) pour configurer une propriété de clichés instantanés comme une clé étrangère (voir occulter les propriétés pour plus d’informations).You can use the string overload of HasForeignKey(...) to configure a shadow property as a foreign key (see Shadow Properties for more information). Nous vous recommandons d’ajouter explicitement la propriété de clichés instantanés pour le modèle avant de l’utiliser comme une clé étrangère (comme indiqué ci-dessous).We recommend explicitly adding the shadow property to the model before using it as a foreign key (as shown below).

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Add the shadow property to the model
        modelBuilder.Entity<Post>()
            .Property<int>("BlogForeignKey");

        // Use the shadow property as a foreign key
        modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts)
            .HasForeignKey("BlogForeignKey");
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog { get; set; }
}

Clé d’entité de sécuritéPrincipal Key

Si vous souhaitez que la clé étrangère à une propriété autre que la clé primaire, vous pouvez utiliser l’API Fluent pour configurer la propriété de clé principale de la relation.If you want the foreign key to reference a property other than the primary key, you can use the Fluent API to configure the principal key property for the relationship. La propriété que vous configurez en tant que le principal est clé automatiquement être configuré en tant qu’une autre clé (voir clés secondaires pour plus d’informations).The property that you configure as the principal key will automatically be setup as an alternate key (see Alternate Keys for more information).

class MyContext : DbContext
{
    public DbSet<Car> Cars { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<RecordOfSale>()
            .HasOne(s => s.Car)
            .WithMany(c => c.SaleHistory)
            .HasForeignKey(s => s.CarLicensePlate)
            .HasPrincipalKey(c => c.LicensePlate);
    }
}

public class Car
{
    public int CarId { get; set; }
    public string LicensePlate { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }

    public List<RecordOfSale> SaleHistory { get; set; }
}

public class RecordOfSale
{
    public int RecordOfSaleId { get; set; }
    public DateTime DateSold { get; set; }
    public decimal Price { get; set; }

    public string CarLicensePlate { get; set; }
    public Car Car { get; set; }
}

Le code suivant montre comment configurer une clé principale.The following code listing shows how to configure a composite principal key.

class MyContext : DbContext
{
    public DbSet<Car> Cars { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<RecordOfSale>()
            .HasOne(s => s.Car)
            .WithMany(c => c.SaleHistory)
            .HasForeignKey(s => new { s.CarState, s.CarLicensePlate })
            .HasPrincipalKey(c => new { c.State, c.LicensePlate });
    }
}

public class Car
{
    public int CarId { get; set; }
    public string State { get; set; }
    public string LicensePlate { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }

    public List<RecordOfSale> SaleHistory { get; set; }
}

public class RecordOfSale
{
    public int RecordOfSaleId { get; set; }
    public DateTime DateSold { get; set; }
    public decimal Price { get; set; }

    public string CarState { get; set; }
    public string CarLicensePlate { get; set; }
    public Car Car { get; set; }
}

Avertissement

L’ordre dans lequel vous spécifiez les propriétés de clé principales doit correspondre à l’ordre dans lequel elles sont spécifiées pour la clé étrangère.The order in which you specify principal key properties must match the order in which they are specified for the foreign key.

Relations obligatoires et facultatifsRequired and Optional Relationships

Vous pouvez utiliser l’API Fluent pour déterminer si la relation est requise ou facultative.You can use the Fluent API to configure whether the relationship is required or optional. Il décide si la propriété de clé étrangère est obligatoire ou facultatif.Ultimately this controls whether the foreign key property is required or optional. Cela est particulièrement utile lorsque vous utilisez une clé étrangère état de clichés instantanés.This is most useful when you are using a shadow state foreign key. Si vous disposez d’une propriété de clé étrangère dans votre classe d’entité, puis le requiredness de la relation est déterminée selon que la propriété de clé étrangère est obligatoire ou facultatif (voir propriétés obligatoires et facultatifs pour plus d’informations plus d’informations).If you have a foreign key property in your entity class then the requiredness of the relationship is determined based on whether the foreign key property is required or optional (see Required and Optional properties for more information).

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts)
            .IsRequired();
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog { get; set; }
}

Suppression en cascadeCascade Delete

Vous pouvez utiliser l’API Fluent pour configurer le comportement de suppression en cascade pour une relation donnée explicitement.You can use the Fluent API to configure the cascade delete behavior for a given relationship explicitly.

Consultez suppression en Cascade dans la section de l’enregistrement des données pour une présentation détaillée de chaque option.See Cascade Delete on the Saving Data section for a detailed discussion of each option.

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts)
            .OnDelete(DeleteBehavior.Cascade);
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

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

Autres modèles de relationOther Relationship Patterns

Un à unOne-to-one

Les relations un à un ont une propriété de navigation de référence sur les deux côtés.One to one relationships have a reference navigation property on both sides. Elles suivent les mêmes conventions que les relations un-à-plusieurs, mais un index unique est présentée sur la propriété de clé étrangère pour vous assurer qu’un seul dépendant est lié à chaque principal.They follow the same conventions as one-to-many relationships, but a unique index is introduced on the foreign key property to ensure only one dependent is related to each principal.

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public BlogImage BlogImage { get; set; }
}

public class BlogImage
{
    public int BlogImageId { get; set; }
    public byte[] Image { get; set; }
    public string Caption { get; set; }

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

Note

EF choisira l’une des entités pour être dépendantes en fonction de sa capacité à détecter une propriété de clé étrangère.EF will choose one of the entities to be the dependent based on its ability to detect a foreign key property. Si l’entité incorrecte est choisie comme dépendantes, vous pouvez utiliser l’API Fluent pour corriger ce problème.If the wrong entity is chosen as the dependent, you can use the Fluent API to correct this.

Lors de la configuration de la relation avec l’API Fluent, vous utilisez la HasOne et WithOne méthodes.When configuring the relationship with the Fluent API, you use the HasOne and WithOne methods.

Lors de la configuration de la clé étrangère, vous devez spécifier le type d’entité dépendante - Notez le paramètre générique fourni pour HasForeignKey dans la liste ci-dessous.When configuring the foreign key you need to specify the dependent entity type - notice the generic parameter provided to HasForeignKey in the listing below. Dans une relation un-à-plusieurs, il est clair que l’entité avec le volet de navigation référence dépend et celle de la collection est le principal.In a one-to-many relationship it is clear that the entity with the reference navigation is the dependent and the one with the collection is the principal. Mais ce n’est pas dans une relation un à un - par conséquent, la nécessité pour le définir explicitement.But this is not so in a one-to-one relationship - hence the need to explicitly define it.

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<BlogImage> BlogImages { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .HasOne(p => p.BlogImage)
            .WithOne(i => i.Blog)
            .HasForeignKey<BlogImage>(b => b.BlogForeignKey);
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public BlogImage BlogImage { get; set; }
}

public class BlogImage
{
    public int BlogImageId { get; set; }
    public byte[] Image { get; set; }
    public string Caption { get; set; }

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

Plusieurs-à-plusieursMany-to-many

Relations plusieurs-à-plusieurs sans une classe d’entité pour représenter la table de jointure ne sont pas encore pris en charge.Many-to-many relationships without an entity class to represent the join table are not yet supported. Toutefois, vous pouvez représenter une relation plusieurs-à-plusieurs en incluant une classe d’entité pour la table de jointure et de deux relations un-à-plusieurs distinct mappage.However, you can represent a many-to-many relationship by including an entity class for the join table and mapping two separate one-to-many relationships.

class MyContext : DbContext
{
    public DbSet<Post> Posts { get; set; }
    public DbSet<Tag> Tags { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<PostTag>()
            .HasKey(t => new { t.PostId, t.TagId });

        modelBuilder.Entity<PostTag>()
            .HasOne(pt => pt.Post)
            .WithMany(p => p.PostTags)
            .HasForeignKey(pt => pt.PostId);

        modelBuilder.Entity<PostTag>()
            .HasOne(pt => pt.Tag)
            .WithMany(t => t.PostTags)
            .HasForeignKey(pt => pt.TagId);
    }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public List<PostTag> PostTags { get; set; }
}

public class Tag
{
    public string TagId { get; set; }

    public List<PostTag> PostTags { get; set; }
}

public class PostTag
{
    public int PostId { get; set; }
    public Post Post { get; set; }

    public string TagId { get; set; }
    public Tag Tag { get; set; }
}