C# Academy · Lektion

Relationer: en-till-många och många-till-många

Modellera och ställ frågor mot en-till-många- och många-till-många-relationer med navigeringsegenskaper och Fluent API.

Lektion 4 av 413 steg

Relationer: en-till-många och många-till-många är en gratis lektion i C# Academy på CoddyKit. Detta är lektion 4 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för C# Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i C# Academy innehåller totalt 4 lektioner.

Relationer i EF Core

EF Core modellerar tre typer av relationer mellan entiteter: en-till-en, en-till-många och många-till-många. Var och en uttrycks med navigeringsegenskaper och konfigureras vid behov med Fluent API.

En-till-många: konfigurera entiteter

En Blog har många Posts. Den beroende entiteten (Post) innehåller den främmande nyckeln. Navigeringsegenskaper på båda sidor gör det möjligt att navigera i båda riktningarna.

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: en-till-många

EF Core härleder relationen enligt konvention, men du kan ange den uttryckligen med Fluent API för tydlighet och för att ställa in beteendet vid kaskadradering.

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

Fråga med Include (eager loading)

Använd Include för att läsa in relaterade data i samma fråga. Använd ThenInclude för att gå djupare i navigeringsgrafen.

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

Många-till-många utan en kopplingsentitet

EF Core 5+ har stöd för många-till-många-relationer utan en uttrycklig kopplingsentitet. Det skapar kopplingstabellen automatiskt utifrån entitetstypernas namn.

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

Många-till-många med en kopplingsentitet

När kopplingstabellen behöver extra kolumner (t.ex. inskrivningsdatum, betyg) skapar du en uttrycklig kopplingsentitet med en sammansatt primärnyckel.

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

Infoga relaterade data

Lägg till relaterade entiteter i den överordnade entitetens samling innan du anropar SaveChangesAsync. EF Core hanterar FK-värden automatiskt.

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

Filtrera på relaterade data

Du kan filtrera på navigeringsegenskaper i LINQ. EF Core översätter automatiskt dessa till SQL JOIN-uttryck.

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

Kaskadradering

Med DeleteBehavior.Cascade tar borttagning av huvudentiteten (Blog) automatiskt alla beroende entiteter (Posts). Övriga alternativ är SetNull, Restrict och 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

Ägda entiteter för värdeobjekt

Ägda entitetstyper passar utmärkt för värdeobjekt (t.ex. Address). De lagras i samma tabell som ägaren och har ingen egen identitet.

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

Praktiskt exempel: Order med OrderLines

Ett komplett e-handelsmönster: Order (huvudentitet) med många OrderLines (beroende entiteter), där varje OrderLine refererar till en 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);

Snabbkontroll

När skapar EF Core automatiskt en kopplingstabell utan en uttrycklig kopplingsentitet?

Repetition: relationer i EF Core

Viktiga lärdomar:

  • En-till-många: främmande nyckel på den beroende entiteten; navigeringsegenskaper på båda sidor; använd Include för att läsa in
  • Många-till-många (enkelt): två ICollection-navigeringar — EF Core skapar automatiskt en kopplingstabell
  • Många-till-många (med extra data): uttrycklig kopplingsentitet med sammansatt primärnyckel
  • Kaskadradering styr vad som händer med beroende entiteter när huvudentiteten tas bort
  • Ägda entiteter modellerar värdeobjekt i samma tabell som ägaren
Gratis att börja

Lär dig C# med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
93
Lektioner
346

Vanliga frågor

Är lektionen ”Relationer: en-till-många och många-till-många” gratis?

Ja – hela texten till ”Relationer: en-till-många och många-till-många” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i C# Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i C# Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Relationer: en-till-många och många-till-många”?

Modellera och ställ frågor mot en-till-många- och många-till-många-relationer med navigeringsegenskaper och Fluent API. Ni övar på C# Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig C# Academy?

Du behöver inga förkunskaper. Utbildningen i C# Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.

Hur lång tid tar lektionen ”Relationer: en-till-många och många-till-många”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här C# Academy-lektionen?

Ja. Varje C# Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Grunderna i DbContext och DbSet
  2. Migreringar och schemamanagement
  3. CRUD-operationer med EF Core
  4. Relationer: en-till-många och många-till-många
← Tillbaka till C# Academy