System.Linq.Dynamic.Core ile Dinamik LINQ Sorguları

System.Linq.Dynamic.Core, .NET ortamında LINQ sorgularını dinamik hale getirmeyi sağlayan bir kütüphanedir. Temel özellikleri şunlardır:

  • Dinamik Sorgu İfadeleri: Sorgularınızı string ifadelerle yazarak, derleme zamanında sabit kodlar yerine çalışma zamanında esnek sorgular oluşturabilirsiniz.
  • Dinamik Filtreleme ve Sıralama: Kullanıcıdan gelen filtre veya sıralama kriterlerini doğrudan sorguya dahil edebilirsiniz.
  • Anonim Tiplerle Seçim: İstenilen alanları dinamik olarak seçmek için Select("new (Field1, Field2)") gibi ifadeler kullanılır.
  • Entity Framework ile Uyum: Özellikle Entity Framework gibi ORM araçlarıyla entegrasyon sağlayarak, veritabanı sorgularında dinamik ifadelerin güvenli bir şekilde kullanılmasını mümkün kılar.

Bu özellikler sayesinde, API filtreleme, raporlama, dinamik veri görselleştirme ve benzeri senaryolarda büyük kolaylık elde edilir.

Kurulum ve Yapılandırma

System.Linq.Dynamic.Core kütüphanesini projeye dahil etmek oldukça basittir. NuGet paket yöneticisini veya .NET CLI’yı kullanarak kütüphaneyi yükleyebilirsiniz.

dotnet add package System.Linq.Dynamic.Core

Visual Studio NuGet Paket Yöneticisi ile Kurulum:

  1. Projenize sağ tıklayın ve “Manage NuGet Packages” seçeneğini seçin.
  2. Browse sekmesinde “System.Linq.Dynamic.Core” araması yapın.
  3. Paketi seçip projeye ekleyin.

Kurulum tamamlandığında, kütüphaneyi projenizin kaynak dosyalarında using System.Linq.Dynamic.Core; ifadesiyle kullanmaya başlayabilirsiniz.

Temel Kullanım ve Sorgu Başlıkları

Kütüphane, LINQ sorgularını dinamik hale getirmek için temel sorgu başlıklarını string ifadeler şeklinde tanımlamanıza olanak tanır. En sık kullanılan sorgu başlıkları şunlardır.

Where – Filtreleme: Belirli bir koşulu sağlayan verileri almak için kullanılır.

var filteredList = people.AsQueryable().Where("Age > 25").ToList();

//Birden fazla koşul
var result = people.AsQueryable().Where("Age > 25 AND Name == \"Ali\"").ToList();

OperatörAçıklamaÖrnek Kullanım
==EşittirWhere("Name == \"Ali\"")
!=Eşit değildirWhere("Age != 30")
>BüyükWhere("Age > 25")
<KüçükWhere("Age < 40")
>=Büyük veya eşitWhere("Age >= 30")
<=Küçük veya eşitWhere("Age <= 30")
AND veya &&Ve (İki koşulun da sağlanması gerekir)Where("Age > 25 AND Name == \"Ali\"")
OR veya ``
Desteklenen Operatörler

OrderBy / OrderByDescending – Sıralama: Bir listeyi belirli bir alan üzerinden sıralamak için kullanılır.

var sortedList = people.AsQueryable().OrderBy("Age").ToList();  // Yaşa göre artan
var sortedListDesc = people.AsQueryable().OrderBy("Age desc").ToList();  // Yaşa göre azalan

Select – Belirli Alanları Seçme: Bir nesnenin sadece belirli alanlarını almak için kullanılır.

var selectedList = people.AsQueryable().Select("new (Name, Age)").ToDynamicList();

Sonuç:

{ Name = Ali, Age = 30 }
{ Name = Veli, Age = 25 }
{ Name = Ayşe, Age = 35 }

GroupBy – Gruplama: Bir koleksiyondaki verileri belirli bir alana göre gruplamak için kullanılır.

var groupedList = people.AsQueryable()
    .GroupBy("Age", "new (Key, Count() as Count)")
    .ToDynamicList();

Bu sorgu şu sonucu döndürür:

{ Key = 30, Count = 1 }
{ Key = 25, Count = 1 }
{ Key = 35, Count = 1 }

Join – Tablo Birleştirme: İki koleksiyonu birleştirmek için Join kullanılır.

var joinedList = db.Customers.Join(
    db.Orders, 
    "CustomerId", 
    "CustomerId", 
    "new (outer.Name, inner.OrderDate)"
).ToDynamicList();

Take ve Skip – Sayfalama (Pagination): Bir sorgudan belirli sayıda veri almak veya belirli sayıda veriyi atlamak için kullanılır.

var pagedList = people.AsQueryable().OrderBy("Name").Skip(5).Take(10).ToList();

Metin Filtreleme (Contains, StartsWith, EndsWith): Metin içeren verileri filtrelemek için kullanılır.

var containsAli = people.AsQueryable().Where("Name.Contains(\"Ali\")").ToList();
var startsWithA = people.AsQueryable().Where("Name.StartsWith(\"A\")").ToList();
var endsWithE = people.AsQueryable().Where("Name.EndsWith(\"e\")").ToList();

Sayısal Fonksiyonlar (Count, Sum, Min, Max, Average): Matematiksel işlemleri yapmak için kullanılır.

var totalOrders = orders.AsQueryable().Select("Count()").FirstOrDefault();
var maxPrice = products.AsQueryable().Select("Max(Price)").FirstOrDefault();
var avgPrice = products.AsQueryable().Select("Average(Price)").FirstOrDefault();

Örnek Uygulama

Aşağıda, basit bir uygulama üzerinden dinamik sorgulamanın nasıl yapılacağına dair örnek bir kod parçası yer almaktadır. Bu örnekte, Person adında bir sınıf üzerinden dinamik filtreleme, sıralama ve seçim işlemleri yapılmaktadır.



namespace DynamicLinqDemo
{
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Örnek veri seti
            var people = new List<Person>
            {
                new Person { Id = 1, Name = "Ali",   Age = 30 },
                new Person { Id = 2, Name = "Veli",  Age = 25 },
                new Person { Id = 3, Name = "Ayşe",  Age = 35 },
                new Person { Id = 4, Name = "Fatma", Age = 28 }
            };

            // Dinamik filtreleme: Yaşı 28'den büyük olanları seç
            string filterQuery = "Age > 28";
            var filteredPeople = people.AsQueryable().Where(filterQuery).ToList();

            Console.WriteLine("Filtrelenmiş Sonuçlar (Age > 28):");
            foreach (var person in filteredPeople)
            {
                Console.WriteLine($"- {person.Name} ({person.Age})");
            }

            // Dinamik sıralama: İsimlere göre azalan sıralama
            string orderByQuery = "Name desc";
            var sortedPeople = people.AsQueryable().OrderBy(orderByQuery).ToList();

            Console.WriteLine("\nSıralanmış Sonuçlar (Name desc):");
            foreach (var person in sortedPeople)
            {
                Console.WriteLine($"- {person.Name} ({person.Age})");
            }

            // Dinamik seçim: Belirli alanları seçme
            string selectFields = "new (Name, Age)";
            var selectedData = people.AsQueryable().Select(selectFields).ToDynamicList();

            Console.WriteLine("\nSeçilen Alanlar:");
            foreach (var item in selectedData)
            {
                Console.WriteLine(item);
            }
        }
    }
}

Bu örneğimizde,

  • "Age > 28" ifadesi ile 28 yaşından büyük kişileri filtreledik.
  • "Name desc" ifadesiyle isimlere göre azalan bir sıralama uyguladık.
  • "new (Name, Age)" ifadesi sayesinde, sadece Name ve Age alanlarını içeren anonim tipler oluşturduk.