Yazılım Mimarileri ve Tasarım Desenleri Üzerine

LINQ TO SQL

LINQ teknolojisi tamamen veri erişim işlemini daha kolay ve anlaşılır hale getirmek amaçlı tasarlanmıştır.Bu veri erişim yöntemleri LINQ TO XML, LINQ TO OBJECT ve LINQ TO SQL olarak veri kaynağına göre değişiklik göstermektedir.Ben burada LINQ TO SQL i anlatacağım.

LINQ TO SQL, LINQ ile yazdığımız komutları ADO.NET providerlarına gönderir.ADO.NET providerları kendilerine gelen ifadeleri database e gönderir.Dönen sonuçlar DataReader tipinden döner(ADO.NET Providerlarına),providerler da sonucu IQueryable tipinden geri gönderirler.

Adı üstünde LINQ TO SQL, yani SQL veri kaynağıyla çalışacağız.
SQL Server’da Northwind veritabanını kullanacağımı belirtmek isterim.
Şimdi LINQ ile SQL veri kaynağında çalışmak istiyorsam eğer, projeme Add New Item ile LINQ TO SQL Clasess eklemeliyiz.

Gördüğünüz gibi uzantısı .dbml olan bir dosyadır.Bu dosyaya kullanacağımız veri tabanındaki tabloları, stored procedure leri, viewleri vs. ekleyeceğiz.Bu sayede bu .dbml uzantılı dosya, arka planda eklenen tablolar için entityler ve koleksiyonlar oluşturacaktır.Genel şablon şu şekilde olacaktır.Northwind tablosundaki Personeller tablosunun entitysi Personeller clası olacakken, koleksiyonu ise Personellers olarak oluşacaktır.
Gördüğünüz gibi ben Northwind.dbml adında bu dosyayı projeme ekliyorum.
Şimdi eklediğimiz Northwind.dbml dosyasını biraz tanıyalım.
Yukarıda da bahsettiğim gibi tablolarımızı, stored proc larımızı ekleyeceğimiz mecradır.Sol tarafa tablolar ve viewleri, sağ tarafada stored procedure leri ekleyeceğiz.

Şimdi SQL Serverımdaki Northwind tablosuna bağlanıp, Northwind.dbml dosyasına tablolarımızı atalım.
Öncelikle Server Explorer penceresine gelelim.Server Explorer pencereniz açık değilse View sekmesinden Server Explorer’ı tıklamanız yeterli olacaktır.

Server Explorer penceresinde Data Connections’a sağ tıklayıp , Add Connection diyerek veritabanını ekleyiniz.
 Bu işlemden sonra Data Connections menüsünde veritabanınız gözükecektir.
Gördüğünüz gibi veritabanının bütün tabloları ve Stored procedurleri olduğu gibi gelmiştir.

İlk etapta örnek olsun diye Müsteriler tablosunu .dbml dosyasına atalım ve üzerinde bir kaç LINQ çalışması yapalım.

Gördüğünüz gibi Musteriler tablosunu sürükledim.Bu sürükleme işlemi bittiği anda, arka plan mantığı hemen devreye giriyor.Yani artık Musteriler tablosunun entitysi ve koleksiyonu oluşturuldu.

Artık LINQ kodları konuşma zamanı geldi.Diğer sayfada programatik olarak LINQ işlemlerine devam edelim.

Bir önceki sayfada Musteriler tablosu Northwind.dbml dosyasına atmıştık.Şimdi bir kaç teferruat kod bilgi verdikten sonra Musteriler tablosuyla ilgili LINQ kod yazacağım.
Öncelikle Northwind.dbml dosyasındaki tabloları, stored procedurleri vs kullanarak LINQ komutları yazmak istiyorsak Northwind.dbml den bir nesne oluşturmamız gerekiyor.Ve bu nesne üzerinde çalışmamız gerekiyor.

NorthwindDataContext Northwind = new NorthwindDataContext();

Gördüğünüz gibi biz Northwind ismi koyduğumuz halde, kendisi NorthwindDataContext olmuş.LINQ da .dbml dosyalarının isimlerinin sonuna DataContext ismini otomatik koyar.

Northwind.Musterilers

NorthwindDataContext nesnesine .(nokta) dediğimizde Musterilers özelliğini görüyoruz.Musteriler tablosunun koleksiyonunu oluşturmuş.Tablonun koleksiyonunu oluşturur ve tablo isminin sonuna çokluk eki olan “s” harfini koyar.
Artık Musteriler tablosunda LINQ komutları çalıştıralım.
Formumuza birer Button ve ListBox nesnesi koyup , işlemlere başlıyorum.
Öncelikle LINQ komutlarıyla tüm müşterileri elde edip ListBox nesnesine yazdıralım.

        NorthwindDataContext Northwind = new NorthwindDataContext();
        private void button1_Click(object sender, EventArgs e)
        {
            var Musteriler = from musteri in Northwind.Musterilers
                             select musteri;
            foreach (var item in Musteriler)
            {
                listBox1.Items.Add(item.MusteriAdi + " " + item.Ulke);
            }
        }

USA’da yaşayan müşterileri çekip, ListBox’a yazdıralım.

        NorthwindDataContext Northwind = new NorthwindDataContext();
        private void button1_Click(object sender, EventArgs e)
        {
            var Musteriler = from musteri in Northwind.Musterilers
                             where musteri.Ulke == "USA"
                             select musteri;
            foreach (var item in Musteriler)
            {
                listBox1.Items.Add(item.MusteriAdi + " " + item.Ulke);
            }
        }

Tabi geriye müşteri nesneleri döndüğünden kesinlikle emin olduğum için, sonuç kümesini var tipinden değilde Musteri tipinden bir koleksiyona atabilirim.

        NorthwindDataContext Northwind = new NorthwindDataContext();
        private void button1_Click(object sender, EventArgs e)
        {
            List Musteriler = (from musteri in Northwind.Musterilers
                                           where musteri.Ulke == "USA"
                                           select musteri).ToList();
            foreach (var item in Musteriler)
            {
                listBox1.Items.Add(item.MusteriAdi + " " + item.Ulke);
            }
        }

USA’da yaşayan müşterilerimi bölgelerine ve şehirlerine göre sıralı bir şekilde getirelim.

        NorthwindDataContext Northwind = new NorthwindDataContext();
        private void button1_Click(object sender, EventArgs e)
        {
            var Musteriler = from musteri in Northwind.Musterilers
                                           where musteri.Ulke == "USA"
                                           orderby musteri.Bolge descending,musteri.Sehir ascending
                                           select musteri;
            foreach (var item in Musteriler)
            {
                listBox1.Items.Add(item.Bolge + " " + item.Ulke);
            }
        }

Kendi belirlediğimiz bir tipi geri döndürelim.

        class KendiMusterim
        {
            public string Ad { get; set; }
            public string Sirket { get; set; }
        }
        NorthwindDataContext Northwind = new NorthwindDataContext();
        private void button1_Click(object sender, EventArgs e)
        {
            var Musteriler = from musteri in Northwind.Musterilers
                             where musteri.Ulke == "USA"
                             orderby musteri.Bolge descending, musteri.Sehir ascending
                             select new KendiMusterim
                             {
                                 Ad = musteri.MusteriAdi,
                                 Sirket = musteri.SirketAdi
                             };
            foreach (var item in Musteriler)
            {
                listBox1.Items.Add(item.Sirket + " " + item.Ad);
            }
        }

Anonymous Type geri dönebiliriz.

        NorthwindDataContext Northwind = new NorthwindDataContext();
        private void button1_Click(object sender, EventArgs e)
        {
            var Musteriler = from musteri in Northwind.Musterilers
                             where musteri.Ulke == "USA"
                             orderby musteri.Bolge descending, musteri.Sehir ascending
                             select new
                             {
                                 Musterininİsmi = musteri.MusteriAdi,
                                 MusterininCalistigiYer = musteri.SirketAdi
                             };
            foreach (var item in Musteriler)
            {
                listBox1.Items.Add(item.Musterininİsmi + " " + item.MusterininCalistigiYer);
            }
        }

Spain ülkesinde yaşayan müşterilerim hangi şehirlerde yaşıyorlar?

        NorthwindDataContext Northwind = new NorthwindDataContext();
        private void button1_Click(object sender, EventArgs e)
        {
            var Musteriler = from musteri in Northwind.Musterilers
                             where musteri.Ulke == "Spain"
                             select musteri.Sehir;
            foreach (var item in Musteriler)
            {
                listBox1.Items.Add(item);
            }
        }

Yukarıdaki kod bloğunu çalıştırdığımız zaman aynı şehirlerin tekrar geldiğini göreceksiniz.Hatırlarsanız SQL komutlarında Distinct yapıyorduk.Aynı şekilde burdada Distinct yapacağız.

        NorthwindDataContext Northwind = new NorthwindDataContext();
        private void button1_Click(object sender, EventArgs e)
        {
            var Musteriler = (from musteri in Northwind.Musterilers
                             where musteri.Ulke == "Spain"
                             select musteri.Sehir).Distinct();
            foreach (var item in Musteriler)
            {
                listBox1.Items.Add(item);
            }
        }

Birazda Satislar tablosunda çalışalım.
Northwind.dbml ye Satislar tablosunu sürükleyip bıraktım.
Gördüğünüz gibi Satislar ile Musteriler tabloları arasında bir constraint mevcut.Bu bağ hakkında gözünüzden kaçmaması gereken detayları iyi takip ediniz.
Eğer bir tabloya bağlı başka bir tablo varsa, nesne üzerinden o nesnenin bağlı olduğu diğer tabloyu koleksiyon olarak elde edebiliriz.
Örneğin,
İsminin içinde “A” harfi geçen müşterilerimize yapılan satışları listeleyim.

        NorthwindDataContext Northwind = new NorthwindDataContext();
        private void button1_Click(object sender, EventArgs e)
        {
            var Sonuc = from musteri in Northwind.Musterilers
                        where musteri.MusteriAdi.Contains("A")
                        select new
                        {
                            MusteriAdi = musteri.MusteriAdi,
                            MusteriSatislari = musteri.Satislars
                        };
            foreach (var musteri in Sonuc)
            {
                listBox1.Items.Add(musteri.MusteriAdi);
                foreach (var satis in musteri.MusteriSatislari)
                {
                    listBox1.Items.Add(" " + satis.SatisID);
                }
            }
        }

Satis_Detaylari tablosunuda Northwind.dbml dosyasına atalım.
Gördüğünüz gibi Satis_Detaylari tablosunun Satislar tablosuyla bir bağlantısı var.

7 nolu ürün toplam kaç adet satılmıştır?

NorthwindDataContext Northwind = new NorthwindDataContext();
var Sonuc = (from satis in Northwind.Satis_Detaylaris
where satis.UrunID == 7
select satis).Count();
MessageBox.Show(Sonuc.ToString());

7 nolu ürünün toplam satış fiyatı nedir?

            NorthwindDataContext Northwind = new NorthwindDataContext();
            var Sonuc = (from satis in Northwind.Satis_Detaylaris
                         where satis.UrunID == 7
                         select satis.BirimFiyati * satis.Miktar).Sum();
            MessageBox.Show(Sonuc.ToString());

7 nolu ürünün ortalama satış fiyatı nedir?

            NorthwindDataContext Northwind = new NorthwindDataContext();
            var Sonuc = (from satis in Northwind.Satis_Detaylaris
                         where satis.UrunID == 7
                         select satis.BirimFiyati * satis.Miktar).Average();
            MessageBox.Show(Sonuc.ToString());

Şimdide Kategoriler ve Ürünler tablosunu Northwind.dbml dosyasına sürükleyelim.
Gördüğünüz gibi Kategoriler ile Urunler tablosu arasında bir bağlantı mevcut.

Beverages kategorisindeki ürünler ?

NorthwindDataContext Northwind = new NorthwindDataContext();
var Sonuc = from urun in Northwind.Urunlers
where urun.Kategoriler.KategoriAdi == "Beverages"
select urun;
foreach (var item in Sonuc)
{
listBox1.Items.Add(item.UrunAdi);
}

Şimdi aşağıdaki örnek kodlara dikkatinizi çekmek istiyorum.

           var deneme1 = from kategori in Northwind.Kategorilers
                where kategori.Urunlers......
           var deneme2 = from urun in Northwind.Urunlers
                where urun.Kategoriler.......

Yukarıdaki gibi iki türlü yazım uygularsanız, Kategoriler tablosundan Urunler tablosuna Urunlers diye ulaşırken, Urunler tablosundan Kategoriler tablosuna Kategoriler diye ulaşıyoruz.
Urunler tablosunun sonuna “s” harfi gelirken neden Kategoriler tablosunun sonuna gelmedi diye sorarsanız eğer her ürünün bir tane Kategorisi olur, ama her kategorinin birden fazla ürünü olabilir.Bu yüzden LINQ teknolojisi programatik zekayada sahip olduğu anlaşılıyor 🙂
20 ya da daha fazla satış yapılan müşterilmiz ?

NorthwindDataContext Northwind = new NorthwindDataContext();
var Sonuc = from musteri in Northwind.Musterilers
where musteri.Satislars.Count >= 20
select new
{
MusteriAdi = musteri.MusteriAdi
};
foreach (var item in Sonuc)
{
listBox1.Items.Add(item.MusteriAdi);
}

Blauer See Delikatessen isimli şirkete yapılan satışların toplam fiyatı?

NorthwindDataContext Northwind = new NorthwindDataContext();
var Sonuc = (from detay in Northwind.Satis_Detaylaris
where detay.Satislar.Musteriler.SirketAdi == "Blauer See Delikatessen"
select detay.Miktar * detay.BirimFiyati).Sum();
listBox1.Items.Add(Sonuc);

LINQ TO SQL hakkındaki yazımda burada son bulmuştur.
Sonraki yazılarımda görüşmek üzere …
İyi Çalışmalar

Mobil sürümden çık