Eager, lazy en explicit loading
Bepaal wanneer gerelateerde gegevens worden geladen met Include, ThenInclude, lazy-loading-proxies en expliciete Load-aanroepen.
Eager, lazy en explicit loading is een gratis C# Academy-les op CoddyKit. Dit is les 1 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.
Drie laadstrategieën
EF Core biedt drie strategieën voor het laden van gerelateerde gegevens: direct laden (samen met de query laden), laden op aanvraag (laden bij toegang) en expliciet laden (laden wanneer je erom vraagt). Met de juiste keuze voorkom je het N+1-probleem en onnodige databaseverzoeken.
Direct laden met Include
Bij direct laden gebruik je Include() om gerelateerde gegevens in dezelfde SQL-query op te nemen met een JOIN. Dit is de meest voorspelbare strategie en voorkomt N+1-problemen.
// 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 voor geneste relaties
ThenInclude gaat dieper de navigatiegrafiek in. Je kunt meerdere niveaus in één query 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();Gefilterd laden met Include
EF Core 5+ ondersteunt het filteren van gerelateerde gegevens binnen Include. Zo kun je een deelverzameling van onderliggende entiteiten laden zonder een afzonderlijke query.
// 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();Laden op aanvraag instellen
Laden op aanvraag laadt navigatie-eigenschappen automatisch wanneer ze voor het eerst worden benaderd. Schakel dit in door het pakket Microsoft.EntityFrameworkCore.Proxies te installeren en UseLazyLoadingProxies() aan te roepen.
// 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>();
}Laden op aanvraag in actie (en de N+1-valkuil)
Laden op aanvraag is handig maar gevaarlijk in lussen — elke toegang start een nieuwe SQL-query, waardoor het N+1-probleem ontstaat. Geef bij lijsten altijd de voorkeur aan direct laden.
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();Expliciet laden
Met expliciet laden kun je een navigatie-eigenschap op aanvraag laden met Entry().Collection().LoadAsync() of Entry().Reference().LoadAsync(). Dit is nuttig wanneer je gerelateerde gegevens alleen onder bepaalde voorwaarden nodig hebt.
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();Expliciet laden met een queryfilter
Je kunt een expliciete laadactie filteren met .Query() voordat je LoadAsync() aanroept, zodat er minder gegevens worden geretourneerd.
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);Gesplitste query's voor grote Include-bewerkingen
Meerdere verzamelingen in één query laden veroorzaakt een Cartesiaanse explosie (het aantal rijen vermenigvuldigt zich). Gebruik AsSplitQuery() om voor elke verzameling een aparte query uit te voeren en de resultaten in het geheugen samen te voegen.
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);Projectie om te veel gegevens ophalen te voorkomen
Laad niet volledige entiteiten met al hun relaties, maar projecteer ze met Select naar een DTO. Zo krijg je in één geoptimaliseerde query precies de gegevens die je nodig hebt.
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 subqueriesPraktijkvoorbeeld: de juiste strategie kiezen
Gebruik in de praktijk deze besliswijzer:
- Eager laden + Include: je hebt de gerelateerde gegevens altijd nodig, bijvoorbeeld op lijstpagina's
- Projectie: alleen-lezenweergaven en API-antwoorden — het efficiëntst
- Expliciet laden: voorwaardelijk laden op basis van de logica van de toepassing
- Lazy laden: vermijd dit in webtoepassingen; gebruik het alleen voor desktop- of scripttoepassingen met kleine gegevensverzamelingen
Korte controle
Wat is het N+1-probleem in de context van lazy laden?
Samenvatting: laadstrategieën
Belangrijkste punten:
- Eager laden (
Include): laadt gegevens in één query — het best bij voorspelbare toegangspatronen - Gefilterde Include: laad slechts een deel van de onderliggende entiteiten — EF Core 5+
- Lazy laden: handig maar riskant — vermijd dit in lussen (N+1-probleem)
- Expliciet laden: laad op aanvraag met nauwkeurige controle
- Projectie met
Select: het efficiëntst voor alleen-leesscenario's - Gesplitste queries: voorkom een Cartesiaanse explosie bij meerdere Include's voor verzamelingen
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 “Eager, lazy en explicit loading” gratis?
Ja — de volledige tekst van “Eager, lazy en explicit loading” 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 “Eager, lazy en explicit loading”?
Bepaal wanneer gerelateerde gegevens worden geladen met Include, ThenInclude, lazy-loading-proxies en expliciete Load-aanroepen. 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 1 van 4.
Hoe lang duurt de les “Eager, lazy en explicit loading”?
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
- Eager, lazy en explicit loading
- Raw SQL, stored procedures en interpolatie
- Gecompileerde query's en prestaties
- Globale queryfilters en owned entities