EFEF Core Handbook

UZMAN

Compiled Queries

Aynı LINQ sorgusu her çağrıda expression tree'den SQL'e yeniden derlenir. Yoğun endpoint'lerde (saniyede binlerce istek) bu derleme maliyeti birikir.

Temel Compiled Query

// Static field olarak tanımla — uygulama ömrü boyunca derleme 1 kere yapılır
public static class ProductQueries
{
    // Tek parametre
    public static readonly Func<AppDbContext, int, Task<Product?>> GetById =
        EF.CompileAsyncQuery(
            (AppDbContext ctx, int id) =>
                ctx.Products.FirstOrDefault(p => p.Id == id));

    // Birden fazla parametre
    public static readonly Func<AppDbContext, int, decimal, IAsyncEnumerable<Product>> 
        GetByCategoryAndMinPrice =
        EF.CompileAsyncQuery(
            (AppDbContext ctx, int categoryId, decimal minPrice) =>
                ctx.Products
                    .Where(p => p.CategoryId == categoryId && p.Price >= minPrice)
                    .OrderBy(p => p.Price));

    // Include ile
    public static readonly Func<AppDbContext, int, Task<Product?>> GetWithCategory =
        EF.CompileAsyncQuery(
            (AppDbContext ctx, int id) =>
                ctx.Products
                    .Include(p => p.Category)
                    .FirstOrDefault(p => p.Id == id));
}

Kullanım

// Controller/Service'de
public class ProductService
{
    private readonly AppDbContext _context;

    public async Task<Product?> GetByIdAsync(int id)
    {
        // ✅ Her çağrıda expression tree parse edilmez
        return await ProductQueries.GetById(_context, id);
    }

    public async Task<List<Product>> GetExpensiveInCategoryAsync(int catId, decimal min)
    {
        var results = new List<Product>();
        await foreach (var product in ProductQueries.GetByCategoryAndMinPrice(_context, catId, min))
        {
            results.Add(product);
        }
        return results;
    }
}

Ne Zaman Compiled Query Kullan?

Durum Compiled Query? Neden
Saniyede yüzlerce kez çalışan endpoint Expression tree her seferinde parse edilmez, doğrudan cache'ten çalışır
Nadir çalışan rapor sorgusu Fark hissedilmez, kod karmaşıklaşır
Dinamik filtre/sıralama gereken sayfa Dynamic where/orderby desteklenmez

Kısıtlamalar:

  • Dynamic where/orderby kullanılamaz
  • Skip/Take parametrik yapılamaz (EF Core 8+: kısıtlı destek)
  • Global Query Filter'lar otomatik uygulanır