0Pricing
C# Academy · Lektion

Beziehungen: Eins-zu-viele und Viele-zu-viele

Modellieren und abfragen Sie Eins-zu-viele- und Viele-zu-viele-Beziehungen mit Navigation Properties und der Fluent API.

Beziehungen: Eins-zu-viele und Viele-zu-viele ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C# Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.

Beziehungen in EF Core

EF Core modelliert drei Arten von Beziehungen zwischen Entitäten: eins-zu-eins, eins-zu-viele und viele-zu-viele. Jede Beziehung wird mit Navigationseigenschaften ausgedrückt und kann optional mit der Fluent API konfiguriert werden.

Eins-zu-viele: Entitäten einrichten

Ein Blog hat viele Posts. Die abhängige Entität (Post) enthält den Fremdschlüssel. Navigationseigenschaften auf beiden Seiten ermöglichen die Navigation in beide Richtungen.

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: Eins-zu-viele

EF Core leitet die Beziehung per Konvention ab. Sie können sie zur besseren Verständlichkeit jedoch mit der Fluent API explizit konfigurieren und das Verhalten beim Kaskadenlöschen festlegen.

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

Mit Include abfragen (Eager Loading)

Verwenden Sie Include, um verbundene Daten in derselben Abfrage zu laden. Mit ThenInclude können Sie tiefer in den Navigationsgraphen vordringen.

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

Viele-zu-viele ohne Join-Entität

EF Core 5+ unterstützt Viele-zu-viele-Beziehungen ohne eine explizite Join-Entität. Die Join-Tabelle wird automatisch anhand der Namen der Entitätstypen erstellt.

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

Viele-zu-viele mit Join-Entität

Wenn die Join-Tabelle zusätzliche Spalten benötigt (z. B. Einschreibedatum oder Note), erstellen Sie eine explizite Join-Entität mit zusammengesetztem Primärschlüssel.

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

Verbundene Daten einfügen

Fügen Sie verbundene Entitäten der Collection des übergeordneten Objekts hinzu, bevor Sie SaveChangesAsync aufrufen. EF Core verwaltet die FK-Werte 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

Nach verbundenen Daten filtern

Sie können in LINQ nach Navigationseigenschaften filtern. EF Core übersetzt diese Filter automatisch in SQL-JOINs.

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

Kaskadenlöschen

Mit DeleteBehavior.Cascade löscht das Löschen der Principal-Entität (Blog) automatisch alle abhängigen Entitäten (Posts). Weitere Optionen sind SetNull, Restrict und 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

Owned-Entitäten für Value Objects

Owned-Entitätstypen eignen sich hervorragend für Value Objects (z. B. Address). Sie werden in derselben Tabelle wie der Besitzer gespeichert und besitzen keine eigenständige Identität.

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

Praxisbeispiel: Order mit Bestellpositionen

Ein vollständiges E-Commerce-Muster: Order (Principal) mit vielen OrderLines (abhängige Entitäten), die jeweils auf ein Product verweisen.

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

Schnelltest

Wann erstellt EF Core automatisch eine Join-Tabelle, ohne dass eine explizite Join-Entität vorhanden ist?

Zusammenfassung: Beziehungen in EF Core

Wichtige Erkenntnisse:

  • Eins-zu-viele: FK auf der abhängigen Entität; Navigation auf beiden Seiten; zum Laden Include verwenden
  • Viele-zu-viele (einfach): zwei ICollection-Navigationen – EF Core erstellt automatisch eine Join-Tabelle
  • Viele-zu-viele (mit zusätzlichen Daten): explizite Join-Entität mit zusammengesetztem PK
  • Kaskadenlöschen steuert, was mit abhängigen Entitäten geschieht, wenn die Principal-Entität entfernt wird
  • Owned-Entitäten modellieren Value Objects in derselben Tabelle wie der Besitzer

Häufig gestellte Fragen

Ist die Lektion „Beziehungen: Eins-zu-viele und Viele-zu-viele“ kostenlos?

Ja — der vollständige Text von „Beziehungen: Eins-zu-viele und Viele-zu-viele“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C# Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Beziehungen: Eins-zu-viele und Viele-zu-viele“?

Modellieren und abfragen Sie Eins-zu-viele- und Viele-zu-viele-Beziehungen mit Navigation Properties und der Fluent API. Du übst C# Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um C# Academy zu starten?

Keine Vorkenntnisse erforderlich. C# Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Beziehungen: Eins-zu-viele und Viele-zu-viele“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser C# Academy-Lektion Code schreiben und ausführen?

Ja. Jede C# Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Grundlagen von DbContext und DbSet
  2. Migrationen und Schemaverwaltung
  3. CRUD-Operationen mit EF Core
  4. Beziehungen: Eins-zu-viele und Viele-zu-viele
← Zurück zu C# Academy