C# Academy · Les

Relaties: one-to-many en many-to-many

Modelleer en bevraag one-to-many- en many-to-many-relaties met navigatie-eigenschappen en de Fluent API.

Les 4 van 413 stappen

Relaties: one-to-many en many-to-many is een gratis C# Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject C# Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus C# Academy bevat in totaal 4 lessen.

Relaties in EF Core

EF Core modelleert drie soorten relaties tussen entiteiten: één-op-één, één-op-veel en veel-op-veel. Elke relatie wordt uitgedrukt met navigatie-eigenschappen en kan desgewenst met de Fluent API worden geconfigureerd.

Eén-op-veel: entiteiten instellen

Een Blog heeft veel Posts. De afhankelijke entiteit (Post) bevat de vreemde sleutel. Navigatie-eigenschappen aan beide kanten maken navigatie in beide richtingen mogelijk.

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
}

Fluent API: één-op-veel

EF Core leidt de relatie standaard af op basis van conventies, maar je kunt deze voor de duidelijkheid expliciet instellen met de Fluent API en zo het gedrag bij trapsgewijs verwijderen bepalen.

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

Query's uitvoeren met Include (direct laden)

Gebruik Include om gerelateerde gegevens in dezelfde query te laden. Gebruik ThenInclude om dieper door de navigatiegrafiek te gaan.

// 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();

Veel-op-veel zonder koppelentiteit

EF Core 5+ ondersteunt veel-op-veelrelaties zonder een expliciete koppelentiteit. Het maakt de koppeltabel automatisch aan op basis van de namen van de entiteitstypen.

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

Veel-op-veel met een koppelentiteit

Als de koppeltabel extra kolommen nodig heeft, zoals een inschrijfdatum of cijfer, maak je een expliciete koppelentiteit met een samengestelde primaire sleutel.

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);

Gerelateerde gegevens invoegen

Voeg gerelateerde entiteiten toe aan de verzameling van een bovenliggende entiteit voordat je SaveChangesAsync aanroept. EF Core verwerkt de waarden van vreemde sleutels automatisch.

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

Filteren op gerelateerde gegevens

Je kunt in LINQ filteren op navigatie-eigenschappen. EF Core vertaalt deze filters automatisch naar SQL JOIN's.

// 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();

Trapsgewijs verwijderen

Met DeleteBehavior.Cascade verwijdert het verwijderen van de hoofdentiteit (Blog) automatisch alle afhankelijke entiteiten (Posts). Andere opties zijn: 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

Entiteiten in eigendom voor waardeobjecten

Entiteitstypen die bij een eigenaar horen zijn ideaal voor waardeobjecten, zoals Address. Ze worden in dezelfde tabel als de eigenaar opgeslagen en hebben geen zelfstandige identiteit.

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);

Praktijkvoorbeeld: Order met bestelregels

Een compleet e-commercepatroon: Order (hoofdentiteit) met veel OrderLines (afhankelijke entiteiten), die elk naar een Product verwijzen.

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);

Snelle controle

Wanneer maakt EF Core automatisch een koppeltabel zonder een expliciete koppelentiteit?

Samenvatting: relaties in EF Core

Belangrijkste punten:

  • Één-op-veel: de vreemde sleutel staat op de afhankelijke entiteit; navigatie aan beide kanten; gebruik Include om te laden
  • Veel-op-veel (eenvoudig): twee ICollection-navigaties — EF Core maakt automatisch een koppeltabel
  • Veel-op-veel (met extra gegevens): expliciete koppelentiteit met samengestelde primaire sleutel
  • Trapsgewijs verwijderen bepaalt wat er met afhankelijke entiteiten gebeurt wanneer de hoofdentiteit wordt verwijderd
  • Entiteiten in eigendom modelleren waardeobjecten in dezelfde tabel als de eigenaar
Gratis beginnen

Leer C# met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
93
Lessen
346

Veelgestelde vragen

Is de les “Relaties: one-to-many en many-to-many” gratis?

Ja — de volledige tekst van “Relaties: one-to-many en many-to-many” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus C# Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus C# Academy bevat in totaal 4 lessen.

Wat leer ik in “Relaties: one-to-many en many-to-many”?

Modelleer en bevraag one-to-many- en many-to-many-relaties met navigatie-eigenschappen en de Fluent API. Je oefent met C# Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met C# Academy te beginnen?

Ervaring vooraf is niet nodig. C# Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “Relaties: one-to-many en many-to-many”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over C# Academy?

Ja. Elke les over C# Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Basisprincipes van DbContext en DbSet
  2. Migraties en schemabeheer
  3. CRUD-bewerkingen met EF Core
  4. Relaties: one-to-many en many-to-many
← Terug naar C# Academy