Dynamic Expression API (Dinamik İfadeler API)

Eyl 06, 2013

LINQ (Language Integrated Query – Dil ile Bütünleştirilmiş Sorgu) yazılım projesi geliştirilen dili (C# - VB) terk etmeden, proje içinden, çeşitli veri kaynaklarına sorgular yapma imkanı sağlayan ortak bir teknolojidir. Öyle ki LINQ teknolojisi sayesinde sadece SQL SERVER ile oluşturulmuş  veri tabanlarındaki tablolardan değil, XML için özelleşmiş .NET sınıflarını kullanmadan XML dosyalarından da veri sorguları yapılabilir.

Dynamic Expression API ya da kısaca Dynamic LINQ mevcut LINQ çekirdeğini daha dinamik sorgular yapabilmek adına genişleten bir kütüphanedir. .Net 3.5 ile hazır gelmeyen harici kütüphanesinde string (karakter dizisi) ifadeler üzerinden dinamik sorgular yapabilen ek metotlar bulundurur. Dinamik sorgular yapabilmek için bu harici kütüphanenin projeye eklenmesi gerekmektedir.  Buradaki dinamik sorgulara, son kullanıcının sorgulama koşullarını belirlediği durumlarda (filtreleme) daha verimli LINQ sorguları yapabilmesine olanak sağladığı durumlar örnek olarak verilebilir. Dynamic Expression API son kullanıcıya, yazılımcının belirlediği değişkenlerin değerlerini değiştirerek sorgu yapmanın yanı sıra, koşul ifadesini bütünüyle "string" bir değer şeklinde alarak, hem değikenlerin kendisini hem de değerlerini belirleyerek sorgu yapma imkanı sağlar. Bu şekilde yapılan sorgular, tam anlamıyla çalışma zamanında (run time) değerlendirileceği için, derleme zamanında (compile time) değerlendirilerek tip güvenliği (type safe) sağlayan klasik LINQ sorgularından ayrılır.

LINQ Uygulaması

Örnek bir veritabanındaki tabloya ait verilere, Bir ASP.NET sayfası içinden, LINQ sorguları yapabilmek için sırasıyla şu adımlar izlenir:

  1. Öncelikle Visual Studio adlı programda File (Dosya) -> New (Yeni) -> Web Site (Web Sitesi) yolu izlenerek yeni bir proje açılır.

  2. Visual Studio programının menüsünde Website (Web Sayfası) sekmesi altındaki Add New Item (Yeni Nesne Ekle) sekmesi tıklanır.



  3. Açılan pencerede LINQ to SQL Classes (SQL Sınıfları için LINQ) sekmesi seçilerek, Add (Ekle) düğmesi tıklanır.



  4. Oluşturulan .dbml uzantılı dosyaya veritabanında bulunan tabloları eklemek için, Server Explorer (Sunucu Gezgini) altında bulunan veritabanından istenen tablolar sürüklenerek sağ taraftaki pencereye bırakılır ve Ctrl + S tuş kombinasyonuyla bu işlem kaydedilir.

  5. Örnek öğrenci tablosundan belli koşulları sağlayan verilere sorgu yapabilmek için şu kod kullanılmıştır:

        protected void Page_Load(object sender, EventArgs e)

        {
            DataClassesDataContext x = new DataClassesDataContext();
            var item = from i in x.ogrencis
                       where i.sınıf < 4
                       select new{i.id,i.ad,i.soyad,i.bölüm,i.sınıf};

            GridView1.DataSource = item;
            GridView1.DataBind();
        }


    Yapılan sorgu sonucunda örnek ögrenci veritabanından, belirlenen koşula göre geri dönen değerler ASP.NET sayfası içinde GridView (Izgara Görünümü)içinde görüntülenir. 

Dynamic LINQ Uygulamaları
Örnek bir veritabanındaki tabloya ait verilere, Bir ASP.NET sayfası içinden, Dynamic LINQ sorguları yapabilmek için sırasıyla şu adımlar izlenir:
  1. Dynamic LINQ uygulaması için izlenecek ilk 4 adım, LINQ uygulamasındaki adımlarla aynıdır.

  2. Örnek veritabanı tabloları .dbml uzantılı dosyaya kaydedildikten sonra, haricen temin edilen Dynamic.cs dosyası Solution Explorer penceresinin üstüne sürüklenip bırakılarak projeye dahil edilir. Kod tarafında ise bu dosyadan faydalanabilmek için System.Linq.Dynamic isim alanının kullanılması gerekmektedir.



  3. Örnek öğrenci tablosundan 4. sınıftan daha küçük sınıfta bulunan öğrencileri sorgulayabilmek için şu kod kullanılmıştır:

        protected void Page_Load(object sender, EventArgs e)
        {

            DataClassesDataContext x = new DataClassesDataContext();
            var item = x.ogrencis
                .Where("sınıf<@0", 4)
                .Select("new(id,ad,soyad,bölüm,sınıf)");

            GridView1.DataSource = item;
            GridView1.DataBind();
        }

  4. Yapılan sorgu sonucunda geri dönen sonuç, örnek LINQ uygulamasında dönen sonuçlar ile aynıdır.



  5. Örnek öğrenci tablosundan 4. sınıftan daha küçük sınıflarda bulunan Telekomünikasyon Müh. bölümü öğrencilerini sorgulayabilmek için şu kod kullanılmıştır:

    protected void Page_Load(object sender, EventArgs e)
    {
            DataClassesDataContext x = new DataClassesDataContext();
            var item = x.ogrencis
                
                .Where("sinif<4 && bolum==@0", "Telekomunikasyon")
                .OrderBy("isim")
                .Select("new(id,isim,bolum,sinif)");

    }

  6. Yapılan sorgu sonucunda geri dönen sonuç şu şekildededir:



  7. Örnek öğrenci tablosundan 4. sınıftan daha küçük sınıflarda okuyan, 19 yaşından büyük Telekomünikasyon Müh. Bölümü öğrencileri dışındaki öğrencileri sorgulayabilmek için şu kod kullanılmıştır:

    protected void Page_Load(object sender, EventArgs e)
    {
            DataClassesDataContext x = new DataClassesDataContext();
            var item = x.ogrencis
                
                .Where("sinif<4 && bolum!=@0 && yas>19", "Telekomunikasyon")
                .OrderBy("sinif")
                .Select("new(id,isim,bolum,sinif)");
    }

  8. Yapılan sorgu sonucunda geri dönen sonuç şu şekildededir:



  9. Örnek öğrenci tablosundan Bilgisayar Müh. Bölümünde okumayan ve 22 yaşından küçük öğrencileri sorgulayabilmek için şu kod kullanılmıştır:

    protected void Page_Load(object sender, EventArgs e)
    {
            DataClassesDataContext x = new DataClassesDataContext();
            string kosul = "bolum!=\"Bilgisayar\" && yas<22";
            var item = x.ogrencis
                
                .Where(kosul)
                .OrderBy("sinif")
                .Select("new(id,isim,bolum,sinif)");       

    }

  10. Dikkat edilirse bu sorguda .Where() metodu içindeki koşul ifadesi doğrudan bir string değil, string tipinde bir değişkendir. Yapılan sorgu sonucunda geri dönen sonuç şu şekildededir:

Dynamic LINQ ile yapılan sorgularda kullanılan metodlar parametre olarak "string" değerler alırlar ve bu değerler üzerinden işlem gerçekleştirirler. Filtreleme yapmak için kullanılan .Where() metodu, içine aldığı katar veya katar" değişkenine göre filtreleme işlemini şekillendirir. Öyle ki bir ASP.NET sayfasındaki kontroller sayesinde, kullanıcı tarafından oluşturulan ve filtreleme koşulunu belirleyecek olan string tipinde bir kosul değişkeni .Where(kosul) şeklinde kullanılarak hem değişkenlerinin (kolon) hem de bu değişkenlerin alacağı değerlerin kullanıcı tarafından belirlendiği sorgu ifadeleri oluşturulabilir. Bu sayede yazılımcı bir tabloda her kolon için ayrı ayrı sorgu metodları yazmak durumunda kalmaz ve tek bir metod sayesinde kullanıcıya sorgu yapma koşullarını belirleme imkanı çalışma zamanında (run-time) sağlanmış olur. Dynamic LINQ bu yönüyle klasik LINQ'den ayrılır.