0Pricing
C# Academy · Lektion

Eager-, Lazy- und Explicit-Loading

Steuern Sie, wann verbundene Daten geladen werden, mit Include, ThenInclude, Lazy-Loading-Proxys und expliziten Load-Aufrufen.

Eager-, Lazy- und Explicit-Loading ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 1 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.

Drei Strategien zum Laden von Daten

EF Core bietet drei Strategien zum Laden verbundener Daten: Eager Loading (gemeinsam mit der Abfrage laden), Lazy Loading (beim Zugriff laden) und Explicit Loading (bei Bedarf laden). Die richtige Wahl verhindert das N+1-Problem und unnötige Roundtrips zur Datenbank.

Eager Loading mit Include

Eager Loading verwendet Include(), um verbundene Daten in derselben SQL-Abfrage per JOIN zu laden. Dies ist die am besten vorhersehbare Strategie und vermeidet N+1-Probleme.

// Single query with JOIN
var blogs = await _db.Blogs
    .Include(b => b.Posts)
    .Where(b => b.IsActive)
    .ToListAsync();

// SQL: SELECT * FROM Blogs LEFT JOIN Posts ON ...

ThenInclude für verschachtelte Beziehungen

ThenInclude führt tiefer in den Navigationsgraphen. Sie können mehrere Ebenen in einer einzigen Abfrage laden.

var orders = await _db.Orders
    .Include(o => o.Customer)
    .Include(o => o.Lines)
        .ThenInclude(l => l.Product)
            .ThenInclude(p => p.Category)
    .Where(o => o.Status == OrderStatus.Pending)
    .ToListAsync();

Gefiltertes Include

EF Core 5+ unterstützt das Filtern verbundener Daten innerhalb von Include. So können Sie eine Teilmenge der untergeordneten Entitäten laden, ohne eine separate Abfrage auszuführen.

// Load only published posts for each blog
var blogs = await _db.Blogs
    .Include(b => b.Posts.Where(p => p.IsPublished)
                         .OrderByDescending(p => p.PublishedAt)
                         .Take(5))
    .ToListAsync();

Lazy Loading einrichten

Lazy Loading lädt Navigationseigenschaften automatisch, sobald erstmals auf sie zugegriffen wird. Aktivieren Sie es, indem Sie das Paket Microsoft.EntityFrameworkCore.Proxies installieren und UseLazyLoadingProxies() aufrufen.

// 1. Install package: dotnet add package Microsoft.EntityFrameworkCore.Proxies
// 2. Enable in DbContext setup:
builder.Services.AddDbContext<AppDbContext>(opt =>
    opt.UseSqlite(connStr)
       .UseLazyLoadingProxies());

// 3. Mark navigation properties as virtual:
public class Blog
{
    public int Id { get; set; }
    public virtual ICollection<Post> Posts { get; set; } = new List<Post>();
}

Lazy Loading in der Praxis (und die N+1-Falle)

Lazy Loading ist praktisch, aber in Schleifen gefährlich – jeder Zugriff löst eine neue SQL-Abfrage aus und verursacht das N+1-Problem. Verwenden Sie in Listenszenarien grundsätzlich Eager Loading.

var blogs = await _db.Blogs.ToListAsync(); // 1 query

foreach (var blog in blogs)
{
    // BAD: each access fires a new query!
    var count = blog.Posts.Count; // N queries
    Console.WriteLine(count);
}

// FIX: Use eager loading
var blogs2 = await _db.Blogs.Include(b => b.Posts).ToListAsync();

Explicit Loading

Mit Explicit Loading können Sie eine Navigationseigenschaft bei Bedarf über Entry().Collection().LoadAsync() oder Entry().Reference().LoadAsync() laden. Dies ist nützlich, wenn Sie verbundene Daten nur unter bestimmten Bedingungen benötigen.

var blog = await _db.Blogs.FindAsync(1); // no posts loaded

// Load posts only when needed
if (needsPosts)
{
    await _db.Entry(blog!)
             .Collection(b => b.Posts)
             .LoadAsync();
}

// Load single reference
var post = await _db.Posts.FindAsync(99);
await _db.Entry(post!)
         .Reference(p => p.Blog)
         .LoadAsync();

Explicit Loading mit Abfragefilter

Sie können einen expliziten Ladevorgang mit .Query() filtern, bevor Sie LoadAsync() aufrufen, und so die zurückgegebene Datenmenge reduzieren.

var blog = await _db.Blogs.FindAsync(1);

// Only load posts published this year
await _db.Entry(blog!)
         .Collection(b => b.Posts)
         .Query()
         .Where(p => p.PublishedAt.Year == DateTime.UtcNow.Year)
         .LoadAsync();

Console.WriteLine(blog!.Posts.Count);

Split-Abfragen für umfangreiche Includes

Das Laden mehrerer Sammlungen in einer Abfrage verursacht eine kartesische Explosion (die Zeilen vervielfachen sich). Verwenden Sie AsSplitQuery(), um für jede Sammlung eine separate Abfrage auszuführen und die Ergebnisse im Arbeitsspeicher zusammenzuführen.

var orders = await _db.Orders
    .Include(o => o.Lines)
    .Include(o => o.Shipments)
    .AsSplitQuery()  // 3 separate SELECTs instead of one giant JOIN
    .ToListAsync();

// Or configure globally:
opt.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);

Projektion zur Vermeidung des Überladens

Anstatt vollständige Entitäten mit all ihren Beziehungen zu laden, erstellen Sie mit Select eine Projektion auf ein DTO. So erhalten Sie in einer einzigen optimierten Abfrage genau die benötigten Daten.

var summaries = await _db.Blogs
    .Select(b => new BlogSummaryDto
    {
        Name      = b.Name,
        PostCount = b.Posts.Count(p => p.IsPublished),
        LatestPost = b.Posts
            .Where(p => p.IsPublished)
            .OrderByDescending(p => p.PublishedAt)
            .Select(p => p.Title)
            .FirstOrDefault()
    })
    .ToListAsync();
// No Include needed - translated to subqueries

Praxisbeispiel: Die richtige Strategie auswählen

Verwenden Sie diesen Entscheidungsleitfaden in der Praxis:

  • Eager + Include: Sie benötigen die verknüpften Daten immer, etwa auf Listenseiten
  • Projection: schreibgeschützte Ansichten und API-Antworten – am effizientesten
  • Explicit: bedingtes Laden auf Grundlage der Anwendungslogik
  • Lazy: in Webanwendungen vermeiden; nur für Desktopanwendungen oder Skripte mit kleinen Datenmengen

Kurzer Check

Was ist das N+1-Problem im Zusammenhang mit Lazy Loading?

Zusammenfassung: Ladestrategien

Wichtigste Erkenntnisse:

  • Eager Loading (Include): lädt Daten mit einer Abfrage – am besten bei vorhersehbaren Zugriffsmustern
  • Filtered Include: lädt nur eine Teilmenge der untergeordneten Elemente – EF Core 5+
  • Lazy Loading: bequem, aber riskant – in Schleifen vermeiden (N+1-Problem)
  • Explicit Loading: lädt Daten bei Bedarf mit feingranularer Kontrolle
  • Projektion mit Select: am effizientesten für schreibgeschützte Szenarien
  • Aufgeteilte Abfragen: verhindern eine kartesische Explosion bei mehreren Includes von Sammlungen

Häufig gestellte Fragen

Ist die Lektion „Eager-, Lazy- und Explicit-Loading“ kostenlos?

Ja — der vollständige Text von „Eager-, Lazy- und Explicit-Loading“ 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 „Eager-, Lazy- und Explicit-Loading“?

Steuern Sie, wann verbundene Daten geladen werden, mit Include, ThenInclude, Lazy-Loading-Proxys und expliziten Load-Aufrufen. 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 1 von 4.

Wie lange dauert die Lektion „Eager-, Lazy- und Explicit-Loading“?

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. Eager-, Lazy- und Explicit-Loading
  2. Rohes SQL, Stored Procedures und Interpolation
  3. Kompilierte Abfragen und Performance
  4. Globale Abfragefilter und Owned Entities
← Zurück zu C# Academy