0Pricing
C# Academy · Leçon

Relations : un-à-plusieurs et plusieurs-à-plusieurs

Modélisez et interrogez les relations un-à-plusieurs et plusieurs-à-plusieurs avec des propriétés de navigation et l’API Fluent.

Relations : un-à-plusieurs et plusieurs-à-plusieurs est une leçon C# Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C# Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C# Academy comprend 4 leçons au total.

Relations dans EF Core

EF Core modélise trois types de relations entre les entités : un-à-un, un-à-plusieurs et plusieurs-à-plusieurs. Chacune est exprimée avec des propriétés de navigation et peut éventuellement être configurée avec l’API Fluent.

Un-à-plusieurs : configuration de l’entité

Un Blog possède plusieurs entités Post. L’entité dépendante (Post) contient la clé étrangère. Les propriétés de navigation des deux côtés permettent de parcourir la relation dans les deux directions.

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; } = "";
    public ICollection<Post> Posts { get; set; } = new List<Post>();
}

public class Post
{
    public int Id { get; set; }
    public string Title { get; set; } = "";
    public int BlogId { get; set; }        // FK
    public Blog Blog { get; set; } = null!; // nav property
}

API Fluent : un-à-plusieurs

EF Core déduit la relation par convention, mais vous pouvez la configurer explicitement avec l’API Fluent pour plus de clarté et pour définir le comportement de suppression en cascade.

protected override void OnModelCreating(ModelBuilder mb)
{
    mb.Entity<Blog>()
      .HasMany(b => b.Posts)
      .WithOne(p => p.Blog)
      .HasForeignKey(p => p.BlogId)
      .OnDelete(DeleteBehavior.Cascade);
}

Interroger avec Include (chargement anticipé)

Utilisez Include pour charger les données associées dans la même requête. Utilisez ThenInclude pour aller plus loin dans le graphe de navigation.

// Load blog with all its posts
var blog = await _db.Blogs
    .Include(b => b.Posts)
    .FirstOrDefaultAsync(b => b.Id == 1);

// Load posts with their comments too
var blogs = await _db.Blogs
    .Include(b => b.Posts)
        .ThenInclude(p => p.Comments)
    .ToListAsync();

Plusieurs-à-plusieurs sans entité de liaison

EF Core 5+ prend en charge les relations plusieurs-à-plusieurs sans entité de liaison explicite. Il crée automatiquement la table de liaison en utilisant les noms des types d’entités.

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; } = "";
    public ICollection<Course> Courses { get; set; } = new List<Course>();
}

public class Course
{
    public int Id { get; set; }
    public string Title { get; set; } = "";
    public ICollection<Student> Students { get; set; } = new List<Student>();
}
// EF creates StudentCourse join table automatically

Plusieurs-à-plusieurs avec une entité de liaison

Lorsque la table de liaison doit contenir des colonnes supplémentaires (par exemple, une date d’inscription ou une note), créez une entité de liaison explicite avec une clé primaire composite.

public class Enrollment
{
    public int StudentId { get; set; }
    public Student Student { get; set; } = null!;
    public int CourseId { get; set; }
    public Course Course { get; set; } = null!;
    public DateTime EnrolledAt { get; set; }
    public decimal? Grade { get; set; }
}

// Fluent API config:
mb.Entity<Enrollment>().HasKey(e => new { e.StudentId, e.CourseId });
mb.Entity<Enrollment>().HasOne(e => e.Student).WithMany(s => s.Enrollments);
mb.Entity<Enrollment>().HasOne(e => e.Course).WithMany(c => c.Enrollments);

Insertion de données associées

Ajoutez les entités associées à la collection du parent avant d’appeler SaveChangesAsync. EF Core gère automatiquement les valeurs FK.

var blog = new Blog { Name = "Dev Notes" };
blog.Posts.Add(new Post { Title = "Hello EF Core" });
blog.Posts.Add(new Post { Title = "Migrations Deep Dive" });

_db.Blogs.Add(blog);
await _db.SaveChangesAsync();
// Inserts Blog + 2 Posts with correct BlogId FK

Filtrage des données associées

Vous pouvez filtrer les propriétés de navigation dans LINQ. EF Core les traduit automatiquement en JOIN SQL.

// Blogs that have at least one published post
var popularBlogs = await _db.Blogs
    .Where(b => b.Posts.Any(p => p.IsPublished))
    .Select(b => new { b.Name, PostCount = b.Posts.Count(p => p.IsPublished) })
    .OrderByDescending(b => b.PostCount)
    .ToListAsync();

Suppression en cascade

Avec DeleteBehavior.Cascade, la suppression de l’entité principale (Blog) supprime automatiquement tous les dépendants (Post). Autres options : SetNull, Restrict, NoAction.

// Delete a blog and all its posts
var blog = await _db.Blogs.FindAsync(1);
_db.Blogs.Remove(blog!);
await _db.SaveChangesAsync();
// Cascade: all Posts with BlogId=1 are also deleted

Entités propriétaires pour les objets-valeurs

Les types d’entités propriétaires conviennent parfaitement aux objets-valeurs (par exemple, Address). Ils sont stockés dans la même table que l’entité propriétaire et n’ont pas d’identité indépendante.

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; } = "";
    public Address ShippingAddress { get; set; } = new();
}

public class Address
{
    public string Street { get; set; } = "";
    public string City { get; set; } = "";
    public string Country { get; set; } = "";
}

// Fluent API:
mb.Entity<Customer>().OwnsOne(c => c.ShippingAddress);

Cas concret : commande avec lignes de commande

Un modèle e-commerce complet : Order (entité principale) avec plusieurs OrderLines (entités dépendantes), chacune faisant référence à un Product.

var order = await _db.Orders
    .Include(o => o.Lines)
        .ThenInclude(l => l.Product)
    .FirstOrDefaultAsync(o => o.Id == orderId);

if (order is null) return Results.NotFound();

var summary = new
{
    OrderId = order.Id,
    Total   = order.Lines.Sum(l => l.Quantity * l.Product.Price),
    Items   = order.Lines.Select(l => new
    {
        l.Product.Name,
        l.Quantity,
        LineTotal = l.Quantity * l.Product.Price
    })
};
return Results.Ok(summary);

Vérification rapide

Quand EF Core crée-t-il automatiquement une table de liaison sans entité de liaison explicite ?

Récapitulatif : relations dans EF Core

Points essentiels :

  • Un-à-plusieurs : FK sur l’entité dépendante ; navigation des deux côtés ; utilisez Include pour charger les données
  • Plusieurs-à-plusieurs (simple) : deux propriétés de navigation ICollection — EF Core crée automatiquement la table de liaison
  • Plusieurs-à-plusieurs (avec données supplémentaires) : entité de liaison explicite avec une PK composite
  • La suppression en cascade détermine ce qui arrive aux dépendants lorsque l’entité principale est supprimée
  • Les entités propriétaires modélisent les objets-valeurs dans la même table que l’entité propriétaire

Questions Fréquemment Posées

La leçon « Relations : un-à-plusieurs et plusieurs-à-plusieurs » est-elle gratuite ?

Oui — le texte complet de « Relations : un-à-plusieurs et plusieurs-à-plusieurs » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C# Academy, passe à CoddyKit PRO. Le cours C# Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Relations : un-à-plusieurs et plusieurs-à-plusieurs » ?

Modélisez et interrogez les relations un-à-plusieurs et plusieurs-à-plusieurs avec des propriétés de navigation et l’API Fluent. Tu pratiques C# Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer C# Academy ?

Aucune expérience préalable n'est requise. C# Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Relations : un-à-plusieurs et plusieurs-à-plusieurs » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon C# Academy ?

Oui. Chaque leçon C# Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Notions de base sur DbContext et DbSet
  2. Migrations et gestion du schéma
  3. Opérations CRUD avec EF Core
  4. Relations : un-à-plusieurs et plusieurs-à-plusieurs
← Retour à C# Academy