LINQ: Language Integrated Query - 1

LINQ: Language Integrated Query - 1 LINQ: Language Integrated Query - 1

Yenilikleri kabullenmeme konusunda son derece başarılı insanlar olduğumuz tartışmasız bir gerçek. .NET Framework"un ülkemizdeki kullanım istatistiğini inceleyecek olursak, çok az sayıda firmanın yeniliklere hızlı bir şekilde adapte olduğunu görürken, büyük çoğunluğun "web servisi mi? o da ne, hem güvenli midir vs.vs." gibi yorumlarla gizliden gizliye "önce diğer firmalar bir denesin, sorun yaşamazlarsa biz de geçeriz" stratejisini izlediklerini görüyoruz. Tabi bu tutumun nedenlerini araştırırken tarihsel geçmişimizi inceleyip genetik bazı sonuçlar çıkarmak mümkünse de, yazgeliştir"de yemek tarifi veren ilk kişi olmanın yanında, tarih makalesi yayınlayan ilk kişi olmayı pek arzu etmiyorum..

Konuya dönecek olursak, büyük çoğunluğunuz duymuştur "Linq" kelimesini, duyan çoğunluğun bir kısmı araştırıp, açılımının Language Integrated Query olduğunu, bu araştırmayı yapanlarında bir kısmı ne işe yaradığını, onlarında bir kısmı detaylarını araştırmıştır. Bu makalede amacım Linq"in ne olduğu, ne amaçla tasarlandığı, ne gibi imkanlar sunduğu gibi bazı konuları açıklığa kavuşturmak. Daha sonraki makalelerle ise Linq"i daha detaylıca ele alıyor olacağım.

Lafı çok uzatıp makaleye varoluşu ele alarak başlamaya gerek yok. Object Oriented yazın, yazmayın veri erişimi bugünün uygulamaları ve servisleri için en önemli konu. Veri erişimi için pek çok farklı yöntem kullanıyoruz. Büyük çoğunluk kendi alışkanlıkları doğrultusunda veri erişim katmanları oluştururken, bazı uygulama geliştiricilerse mevcut bazı veri erişim modellerini kullanmayı tercih ediyor. Dikkat etmemiz gereken nokta ise, kullandığımız dilin sunduğu imkanlar doğrultusunda veri erişimini sağlayacak bir yapının ortaya çıkarılmaya çalışılıyor olması. Geldiğimiz noktada veri kaynağı olarak xml ve ilişkisel veritabanları en yoğun kullanılan seçenekler. Linq"in çıkış noktası ise, programlama dilinin özelliklerini kullanarak tek bir veri kaynağına erişmemizi mümkün kulan bir yapı ortaya çıkartmak yerine, daha genel bir yaklaşımla veri erişimini programlama dilinin bir özelliği olarak sunmaktır. Örneğin, C# dilini kullanarak, SQL dili ile yazdıklarımıza benzer, dinamik sql ifadeleri ile elde ettiğimiz esnekliği ve stored procedure"lar ile elde ettiğimiz etkin ve güvenli yapıya benzer bir sorgulamayı, IntelliSense ve compile-time tür denetimi gibi özelliklerle yazabilmek.. Hikaye gibi anlattım, şimdi işte Linq bunları sağlar, buradanda download edip kullanabilirsiniz demeyi isterdim ama, malesef henüz (tam olarak) o noktada değiliz. Ama bu anlattıklarımı Linq neyi amaçlar sorusunun cevabı olarak kabul edebilirsiniz. Aslında bulunduğumuz noktada (yani Framework 3.5 Beta aşamasında) belirttiğim noktaya gelmiş sayılırız ancak tam anlamıyla bu noktadayız diyebileceğimiz tarih, Visual Studio"nun bir sonraki sürümünün (Orcas) yayınlandığı tarihtir.

Pekala, Linq uygulamada bize ne sağlıyor? Uygulama ile görelim. 

Örnek uygulamamızda Sporcular adında, kürekçi bilgileri içeren bir classımız olacak. Bu classın içinde sporcuya ait ad, soyad, hangi sınıfta yarıştığı, hangi tekne ile yarıştığı (gerçi genellikle bir kürekçi birden fazla tekne ile yarışa çıkar ama işi fazla detaylandırmaya gerek yok) ve doğum tarihi bilgilerini içeren propertyler olacak.

Uygulamamızın arayüzü aşağıdaki gibi olacak:

Sporcu classı

public class Sporcu {    public enum TekneTurleri    {         Tek_Çifte,         İki_Çifte,         İki_Tek,         Dört_Çifte,         Dört_Tek,         Sekiz_Tek     }

    public enum YarisKategorileri    {         Genc_C,         Genc_B,         Genc_A,         Büyük_B,         Büyük_A,         Kıdemli_A,         Kıdemli_B,         Kıdemli_C,         Hafif_Kilo     }     private string _ad, _soyad;    private YarisKategorileri _yarisKategorisi;    private TekneTurleri _tekneTuru;    private DateTime _dogumTarihi; 

    public string Ad     {         get { return _ad; }         set { _ad = value; }     }

    public string Soyad     {         get { return _soyad; }         set { _soyad = value; }     }

    public YarisKategorileri YarisKategorisi     {         get { return _yarisKategorisi; }         set { _yarisKategorisi = value; }     }

    public TekneTurleri TekneKategorisi     {         get { return _tekneTuru; }         set { _tekneTuru = value; }     }

    public DateTime DogumTarihi     {         get { return _dogumTarihi; }         set { _dogumTarihi = value; }     } 

    public Sporcu(string Ad, string Soyad, YarisKategorileri yarisKategorisi, TekneTurleri tekneTuru, DateTime dogumTarihi)    {         _ad = Ad;         _soyad = Soyad;         _dogumTarihi = DogumTarihi;         _tekneTuru = tekneTuru;         _yarisKategorisi = yarisKategorisi;          _dogumTarihi = dogumTarihi;    }}

Uygulama kodlarının daha az karmaşık olması için Sporcu classından nesneler oluşturarak liste olarak bize sunacak bir Sporcular classı oluşturuyorum.

Sporcular classı

public class Sporcular : List{     public Sporcular()

    {

        Add(new Sporcu("Kadir", "Sümerkent", Sporcu.YarisKategorileri.Büyük_A, Sporcu.TekneTurleri.Tek_Çifte,Convert.ToDateTime("01.01.1980")));

        Add(new Sporcu("Nancy", "Davolio", Sporcu.YarisKategorileri.Büyük_A, Sporcu.TekneTurleri.Tek_Çifte, Convert.ToDateTime("02.02.1980")));

        Add(new Sporcu("Andrew", "Fuller", Sporcu.YarisKategorileri.Büyük_A, Sporcu.TekneTurleri.Tek_Çifte, Convert.ToDateTime("03.03.1980")));

        Add(new Sporcu("Janet", "Leverling", Sporcu.YarisKategorileri.Büyük_A, Sporcu.TekneTurleri.Tek_Çifte, Convert.ToDateTime("04.04.1980")));

        Add(new Sporcu("Margaret", "Peacock", Sporcu.YarisKategorileri.Büyük_A, Sporcu.TekneTurleri.Tek_Çifte, Convert.ToDateTime("05.05.1980")));

        Add(new Sporcu("Steven", "Buchanan", Sporcu.YarisKategorileri.Büyük_A, Sporcu.TekneTurleri.Tek_Çifte, Convert.ToDateTime("06.06.1980")));

        Add(new Sporcu("Michael", "Suyama", Sporcu.YarisKategorileri.Büyük_A, Sporcu.TekneTurleri.Tek_Çifte, Convert.ToDateTime("07.07.1980")));

        Add(new Sporcu("Robert", "King", Sporcu.YarisKategorileri.Büyük_A, Sporcu.TekneTurleri.Tek_Çifte, Convert.ToDateTime("08.08.1980")));

        Add(new Sporcu("Laura", "Callahan", Sporcu.YarisKategorileri.Büyük_A, Sporcu.TekneTurleri.Tek_Çifte, Convert.ToDateTime("09.09.1980")));

        Add(new Sporcu("Anne", "Dodsworth", Sporcu.YarisKategorileri.Büyük_A, Sporcu.TekneTurleri.Tek_Çifte, Convert.ToDateTime("10.10.1980")));

    }} 

Şimdi Formun load olayında, form üzerinde ilgili combobox kontrollerine yarış kategorileri ve tekne türlerini ilgili enumerationlardan yükleyecek ve tüm sporcuların listesini listview"a yükleyecek kodları yazıyorum, aynı zamanda tüm prosedürlerden erişebilmek için sporcular nesnesini prosedürlerin dışında tanımlıyorum:

Form_Load olayı

Sporcular sporcular = new Sporcular();

private void Form1_Load(object sender, EventArgs e) {  comboBox1.DataSource = Enum.GetNames(typeof(Sporcu.TekneTurleri));  comboBox2.DataSource = Enum.GetNames(typeof(Sporcu.YarisKategorileri));

  for (int i = 0; i < sporcular.Count; i++)  {    listView1.Items.Add(sporcular[i].Ad);    listView1.Items[i].SubItems.Add(sporcular[i].Soyad);    listView1.Items[i].SubItems.Add(sporcular[i].YarisKategorisi.ToString());    listView1.Items[i].SubItems.Add(sporcular[i].TekneKategorisi.ToString());    listView1.Items[i].SubItems.Add(sporcular[i].DogumTarihi.ToShortDateString());  }}

Uygulamayı çalıştırdığımda şu aşamada gördüğümüz ekran aşağıdaki gibidir:

Şimdi Linq öncesinde bu liste içinde ismi Robet olan sporcunun detaylarını almak istediğimizde yazacağımız (Button1"in Click eventında) koda bir bakalım:

Button1_Click olayı

listView1.Items.Clear();

for (int i = 0; i < sporcular.Count; i++) {  if (sporcular[i].Ad = textBox1.Text)  {   listView1.Items.Add(sporcular[i].Ad);   listView1.Items[listView1.Items.Count - 1].SubItems.Add(sporcular[i].Soyad);   listView1.Items[listView1.Items.Count - 1].SubItems.Add(sporcular[i].YarisKategorisi.ToString());   listView1.Items[listView1.Items.Count - 1].SubItems.Add(sporcular[i].TekneKategorisi.ToString());   listView1.Items[listView1.Items.Count - 1].SubItems.Add(sporcular[i].DogumTarihi.ToShortDateString());   }}

Gördüğünüz gibi mevcut imkanlarla bu işlemi yapmak için akla gelen yöntemlerden ilki bir for döngüsü kullanmak. Tabi işimiz her zaman bu kadar kolay olmayabilir. Bu kodu sonuçları birden çok kritere göre filtreleyecek ve belirttiğimiz bir property"e göre sıralayacak şekilde güncelleyecek olursak işi epey uzatmış oluruz. Ancak bu detaylı isteğimizi Linq ile kolayca gerçekleştirebiliriz. Şöyle ki:

Button1_Click olayı (Linq ile yazılmış olan)

//Sporcu ismine göre arama yapıyoruzvar a = from s in sporcular where s.Ad == textBox1.Text orderby s.Ad descending select s; 

//buradan sonrası listview"ı doldurmakla ilgili listView1.Items.Clear();foreach (var result in a) { listView1.Items.Add(result.Ad); listView1.Items[listView1.Items.Count-1].SubItems.Add(result.Soyad); listView1.Items[listView1.Items.Count - 1].SubItems.Add(result.YarisKategorisi.ToString()); listView1.Items[listView1.Items.Count - 1].SubItems.Add(result.TekneKategorisi.ToString()); listView1.Items[listView1.Items.Count - 1].SubItems.Add(result.DogumTarihi.ToShortDateString());}

Gördüğünüz gibi bu filtrelemeyi sporcular adlı liste içinde yapmak için herhangi bir döngü kullanmadan, sql"e oldukça benzer bir ifade ile oluşturduk ve sonuçları listview"a ekledik. Formumuza Soyad, Tekne Türü ve yarış Kategorisi ile ilgili arama kodlarını da ekleyelim:

Button2_Click olayı (Linq)

//Sporcu soyadına göre arama yapıyoruzvar a = from s in sporcular where s.Soyad == textBox2.Text orderby s.Ad descending select s; 

//buradan sonrası listview"ı doldurmakla ilgili listView1.Items.Clear();foreach (var result in a) { listView1.Items.Add(result.Ad); listView1.Items[listView1.Items.Count-1].SubItems.Add(result.Soyad); listView1.Items[listView1.Items.Count - 1].SubItems.Add(result.YarisKategorisi.ToString()); listView1.Items[listView1.Items.Count - 1].SubItems.Add(result.TekneKategorisi.ToString()); listView1.Items[listView1.Items.Count - 1].SubItems.Add(result.DogumTarihi.ToShortDateString());}

Button3_Click olayı (Linq)

//Tekne türüne göre arama yapıyoruzvar a = from s in sporcular where s.TekneKategorisi.ToString() == comboBox1.SelectedItem.ToString() orderby s.Ad descending select s;

//buradan sonrası listview"ı doldurmakla ilgili listView1.Items.Clear();foreach (var result in a) { listView1.Items.Add(result.Ad); listView1.Items[listView1.Items.Count-1].SubItems.Add(result.Soyad); listView1.Items[listView1.Items.Count - 1].SubItems.Add(result.YarisKategorisi.ToString()); listView1.Items[listView1.Items.Count - 1].SubItems.Add(result.TekneKategorisi.ToString()); listView1.Items[listView1.Items.Count - 1].SubItems.Add(result.DogumTarihi.ToShortDateString());}

Button4_Click olayı (Linq)

//Yarış kategorisine göre arama yapıyoruzvar a = from s in sporcular where s.YarisKategorisi.ToString() == comboBox2.SelectedItem.ToString() orderby s.Ad descending select s;

//buradan sonrası listview"ı doldurmakla ilgili listView1.Items.Clear();foreach (var result in a) { listView1.Items.Add(result.Ad); listView1.Items[listView1.Items.Count-1].SubItems.Add(result.Soyad); listView1.Items[listView1.Items.Count - 1].SubItems.Add(result.YarisKategorisi.ToString()); listView1.Items[listView1.Items.Count - 1].SubItems.Add(result.TekneKategorisi.ToString()); listView1.Items[listView1.Items.Count - 1].SubItems.Add(result.DogumTarihi.ToShortDateString());}

Gördüğünüz gibi Linq ile elimizdeki liste içinde filtreleme yapmak için artık programlama dili ile döngüler oluşturup içinde kaybolmak yerine, zaten aşina olduğumuz sql diline oldukça yakın bir sözdizimi ile, son derece esnek ve güçlü bir sorgulama altyapısına sahip durumdayız. Linq"i denemek, kendini bu konuda geliştirmek isteyenler Visual Studio Orcas"ın Beta sürümlerini veya Orcas Express Edition"ları bu sayfadan bulabilirler.Bir sonraki makalede Linq"in altyapısını daha detaylı olarak ele alacak ve örneklerimizi geliştiriyor olacağız.Makalede geliştirdiğim uygulamayı download etmek için burayı tıklayın.

Döküman Arama

Başlık :

ERKAN MAKİNA / ALİ ERKANKapat