EF Core'da change tracking nasıl çalışır? AsNoTracking ne zaman kullanılır ve N+1 problemi nasıl önlenir?
Cevap
DbContext, sorguyla yüklediği her entity'nin bir kopyasını (snapshot) change tracker'da tutar. SaveChanges() çağrıldığında mevcut değerleri snapshot ile karşılaştırır ve yalnızca değişen alanlar için UPDATE üretir. Entity durumları: Added, Unchanged, Modified, Deleted, Detached.
var user = await db.Users.FirstAsync(u => u.Id == id); // tracked
user.Email = "yeni@ornek.com";
await db.SaveChangesAsync(); // UPDATE Users SET Email = @p WHERE Id = @idAsNoTracking
Yalnızca okuma yapılan sorgularda (listeleme, rapor, API GET) tracking gereksiz bellek ve CPU harcar.
var list = await db.Products.AsNoTracking()
.Where(p => p.IsActive)
.Select(p => new ProductDto(p.Id, p.Name, p.Price)) // projection
.ToListAsync();Select ile DTO'ya projection yapılan sorgular zaten track edilmez. Tüm context için varsayılanı UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking) ile değiştirebilirsiniz.
N+1 problemi
var orders = await db.Orders.ToListAsync(); // 1 sorgu
foreach (var o in orders)
Console.WriteLine(o.Customer.Name); // lazy loading açıksa N sorguÇözümler:
- Eager loading:
db.Orders.Include(o => o.Customer).ThenInclude(...) - Projection:
Select(o => new { o.Id, CustomerName = o.Customer.Name })tek bir JOIN üretir. - Birden fazla koleksiyon Include ediliyorsa kartezyen patlamayı önlemek için
AsSplitQuery(). - Lazy loading proxy'lerini (
UseLazyLoadingProxies) varsayılan olarak açmayın.
Toplu işlemler
EF Core 7+ ExecuteUpdateAsync / ExecuteDeleteAsync ile entity yüklemeden tek SQL ile toplu güncelleme/silme yapılabilir.
await db.Sessions.Where(s => s.ExpiresAt < now).ExecuteDeleteAsync();İlgili C# & .NET soruları
- .NET'te Garbage Collector nasıl çalışır? Generation'lar, Large Object Heap ve IDisposable ilişkisini açıklayın.
- IEnumerable<T> ile IQueryable<T> arasındaki fark nedir? EF Core'da yanlış kullanım ne gibi sorunlara yol açar?
- LINQ'te deferred execution nedir? Aşağıdaki kodun çıktısı ne olur?
- async/await kullanırken .Result veya .Wait() çağırmak neden deadlock'a yol açabilir? ConfigureAwait(false) ne işe yarar?
- ASP.NET Core DI'da Transient, Scoped ve Singleton lifetime'ları arasındaki fark nedir? Captive dependency nedir?
- ASP.NET Core'da middleware pipeline nasıl çalışır? Use, Run ve Map farkı nedir, sıralama neden önemlidir?
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.