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 = @id

AsNoTracking

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();
  1. .NET'te Garbage Collector nasıl çalışır? Generation'lar, Large Object Heap ve IDisposable ilişkisini açıklayın.ZorC# & .NETBackend
  2. IEnumerable<T> ile IQueryable<T> arasındaki fark nedir? EF Core'da yanlış kullanım ne gibi sorunlara yol açar?KolayC# & .NETBackend
  3. LINQ'te deferred execution nedir? Aşağıdaki kodun çıktısı ne olur?OrtaC# & .NETBackend
  4. async/await kullanırken .Result veya .Wait() çağırmak neden deadlock'a yol açabilir? ConfigureAwait(false) ne işe yarar?ZorC# & .NETBackend
  5. ASP.NET Core DI'da Transient, Scoped ve Singleton lifetime'ları arasındaki fark nedir? Captive dependency nedir?OrtaC# & .NETBackend
  6. ASP.NET Core'da middleware pipeline nasıl çalışır? Use, Run ve Map farkı nedir, sıralama neden önemlidir?OrtaC# & .NETBackend

Bu konuda başka bir soru biliyor musun?

Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.

Soru ekle