Skip to content

Dynamic Linq sorgularında Relation

Uzun bir süredir yine blogu birbaşına bırakmış olmamın verdiği hüznü derin derin içimde hissederken ilginç bir durumu paylaşayım istedim. Bir linq sorgusu yazacaksınız ve kıstaslarınız dinamik olarak, çalışma zamanında belirlenecek. Kısaca linq içerisinde yazacağınız WHERE expression duruma göre değişecek. Nasıl böyle bir gereklilik doğar; örneğin bir adres defteri sorgusu alacaksınız, bir kullanıcı gider sadece adı ahmet olanları listelemek ister, bir diğeri adı ahmet ve telefon no’sunda 9 geçenler listelemek ister. Bu örnekte kıstas en fazla 2 tane olduğu için bir sorun yok belki, iki ayrı linq sorgusu yazarsanız, ancak bu tip kıstaslarınızın sayısı arttıkça iş içinden çıkılmaz olur. Bu durumlar için şu şekilde bir çözüm geliştirilmiş. Çok ayrıntılı inceleyemedim fakat tek tablolu sorgularınızda gayet başarılı sonuçlar veriyor gibi.

Ancak bu yazının konusu biraz daha karışık, 1 ana tablo ve ona bağlı 2 adet yan tablo var diyelim. Bu durumda dinamic linq sorgusu nasıl olacak. Öncelikle örnek tabloların yapılarını verelim;

KISI tablosu
ID uniqueidentifier
ISIM nvarchar(50)

KISI.UNVAN tablosu
ID uniqueidentifier
UNVAN nvarchar(50)

KISI.TELEFONLAR tablosu
ID uniqueidentifier
KISI_ID uniqueidentifier
TELEFON nvarchar(20)

görülebileceği üzere, KISI ve KISI.UNVAN tabloları arasında ID ler üzerinden bir One To One Relation varken KISI ve KISI.TELEFONLAR tabloları arasında ID -> KISI_ID eşleşmesi ile kurulmuş bir One To Many Relation mevcut.

Linq içerisinde bu tip durumlara çare olabilecek bir fonksiyon mevcut. Bu fonksiyon generic bir fonksiyon ve t-sql olarak sorguyu girdi olarak verdiğinizde size linq sorgusunda olduğu gibi IEnumerable bir sonuç döndürüyor. Basit bir örnekle açıklayalım;

 Dim db As New DBDataContext
        Dim sqlTxt As String = "SELECT DISTINCT k.* FROM KISI k " & _
                                "LEFT OUTER JOIN [KISI.UNVAN] ku ON k.ID = ku.ID " & _
                                "LEFT OUTER JOIN [KISI.TELEFONLAR] kt ON kt.KISI_ID = k.ID " & _
                                "WHERE k.ISIM LIKE '%1%' AND ku.UNVAN LIKE '%1%' AND kt.TELEFON LIKE '%1%' " & _
                                "ORDER BY k.ISIM"
        Dim kisiler = db.ExecuteQuery(Of KISI)(sqlTxt)

İlk olarak yıllardır olduğu üzere tabloları birbiriyle bağlayan ve sonra bu bağlantılar sonucu oluşan tablodan filtreleme yapan sorguyu oluşturduk. Bu sorgunun WHERE sonrası kısmı tamamiyle size kalmış, bağlı 3 tablonun istenilen kolonu ile ilgili kıstaslar buraya yazılabilir. Bu sql sorgusu oluşturulduktan sonra ilk satırda yarattığımız linq data context’in ExecuteQuery generic fonksiyonunu çağırıyoruz. Generic fonksiyona tip girdisi olarak KISI verdiğimizden çıktı olarak bize IEnumerable(Of KISI) tipinde bir çıktı üretecek. Burada dikkat edilmesi gereken tek nokta DISTINCT kelimesi. Eğer One To Many bir relation kullanılmayacaksa pektabi bu kelimeye ihtiyaç olmayacak ama bu örnekte aksi bir durum söz konusu olduğundan DISTINCT kelimesi kullanmak zorundayız. Eğer bu kelime olmazsa sonuçlar içerisinde tamamen aynı bilgileri içeren birden fazla veriyle karşılaşırız.

3J’ler yazısının 2. bölümünü yayınlayacağım en kısa zamanda, ısrarla bekleyiniz…

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*