TEKNİK YAZI / NOTLAR

LINQ: C# ile Bildirimsel Veri Sorgulama

LINQ nedir, nasıl çalışır? C#'ta veri sorgulama ve manipülasyonun en güçlü aracını keşfedelim.

LINQ (Language Integrated Query), koleksiyonlar ve sorgu sağlayıcıları üzerinde filtreleme, dönüştürme, gruplama ve sıralama işlemlerini C# dil yapılarıyla ifade etmeyi sağlar. Aynı sözdizimi benzer görünse de IEnumerable<T> ile bellek içinde çalışan sorgular ve IQueryable<T> üzerinden başka bir dile çevrilen sorgular farklı yürütme özelliklerine sahiptir.

LINQ Nedir? Problem Ne?

İç içe döngüler, koşullar ve geçici listelerle yazılan bir veri dönüşümü LINQ ile daha bildirimsel ifade edilebilir. Bu kısalık tek başına performans garantisi değildir; sorgunun ne zaman çalıştığını ve sağlayıcının ifadeyi nasıl çevirdiğini bilmek gerekir.

LINQ bu problemi çözüyor. Declarative bir yaklaşımla, ne istediğinizi söylüyorsunuz, nasıl yapılacağıyla uğraşmıyorsunuz. SQL yazmışlığınız varsa, mantık çok tanıdık gelecek. Ama LINQ sadece database query’si değil - array’ler, list’ler, XML, JSON, hatta custom object’ler üzerinde çalışıyor!

İki Farklı Syntax: Query vs Method

LINQ’nun iki farklı yazım şekli var ve ikisi de aynı işi yapıyor:

Query Syntax: SQL’e benzer, daha okunabilir Method Syntax: Functional programming tarzı, daha güçlü ve esnek

Hangisini kullanacağınız tamamen tercihinize bağlı. Çoğu developer method syntax’ı tercih ediyor çünkü daha fazla özellik sunuyor ve IntelliSense desteği daha iyi.

LINQ’nun Gücü: Deferred Execution

LINQ’nun en önemli özelliklerinden biri deferred execution (ertelenmiş çalıştırma). Query’nizi tanımladığınızda hemen çalışmaz! Sadece sonuca gerçekten ihtiyacınız olduğunda (ToList(), FirstOrDefault(), Count() gibi) çalışır.

Deferred execution, sorgu tanımının sonuçlar enumerate edilene kadar çalışmaması demektir. Aynı sorguyu daha sonra tekrar enumerate etmek değişmiş kaynak üzerinde yeni sonuç üretebilir; bu davranış gereksiz işi azaltabileceği gibi beklenmeyen tekrar sorgulara da yol açabilir.

LINQ Providers - Her Yerde LINQ

LINQ’nun sihri provider’larında. Farklı veri kaynaklarıyla çalışmak için farklı provider’lar var:

En güzeli? Aynı syntax’ı hepsiyle kullanıyorsunuz!

Basit Örnekler

// Sample data
var products = new List<Product>
{
    new Product { Id = 1, Name = "Laptop", Price = 1000, Category = "Electronics" },
    new Product { Id = 2, Name = "Mouse", Price = 20, Category = "Electronics" },
    new Product { Id = 3, Name = "Book", Price = 15, Category = "Education" }
};

// Method syntax - Filter and project
var expensiveItems = products
    .Where(p => p.Price > 50)
    .Select(p => new { p.Name, p.Price })
    .OrderByDescending(p => p.Price);

// Query syntax - Same result
var expensiveItemsQuery =
    from p in products
    where p.Price > 50
    orderby p.Price descending
    select new { p.Name, p.Price };

// Grouping example
var productsByCategory = products
    .GroupBy(p => p.Category)
    .Select(g => new
    {
        Category = g.Key,
        Count = g.Count(),
        TotalValue = g.Sum(p => p.Price)
    });

Method Chaining - LINQ’nun Güzelliği

LINQ method’ları chainlenebilir. Bu fluent interface sayesinde kompleks query’leri okunabilir şekilde yazabiliyorsunuz:

var result = customers
    .Where(c => c.Age > 18)                    // Filter adults
    .OrderBy(c => c.LastName)                  // Sort by last name
    .ThenBy(c => c.FirstName)                  // Then by first name
    .Skip(10)                                   // Skip first 10
    .Take(20)                                   // Take next 20
    .Select(c => c.Email)                      // Get only emails
    .Distinct()                                 // Remove duplicates
    .ToList();                                  // Execute and materialize

LINQ vs SQL

LINQ SQL’den ilham almış ama farklılıklar var:

Type Safety: LINQ compile-time type checking yapıyor. SQL syntax error’ları runtime’da çıkar.

IntelliSense: IDE size yardım ediyor. Property isimleri, method’lar otomatik tamamlanıyor.

Refactoring: Property ismi değişince, LINQ query’leri otomatik güncelleniyor.

Debugging: LINQ query’lerini debug edebilirsiniz. Breakpoint koyup, step-by-step ilerleyebilirsiniz.

Anonymous Types ve Projection

LINQ’nun harika özelliklerinden biri anonymous type’lar. Query sonucunda yeni tipler oluşturabiliyorsunuz:

// Create new shape without defining a class
var summary = orders
    .Select(o => new
    {
        o.CustomerId,
        o.OrderDate,
        Year = o.OrderDate.Year,
        Total = o.OrderItems.Sum(i => i.Price * i.Quantity)
    });

Real World Kullanım

Sonuç

LINQ, C# developer’ının olmazsa olmazı. Veri manipülasyonunu o kadar kolaylaştırıyor ki, bir kere öğrenince onsuz kod yazmak istemiyorsunuz. SQL bilgisi olanlar için learning curve düşük, ama gücü muazzam.

En güzel yanı? Her yerde kullanabiliyorsunuz. Database query’lerinden, in-memory collection’lara, XML’den JSON’a… Aynı syntax, aynı pattern’ler.