LINQ to SQL

Bu makalemde sizlere visual studio 2008’le gelen yeni bir teknolojiden bahsedeceğim.LINQ büyük ölçüde veritabanı bağımsız çalışmamıza olanak sağlayan ve veritabanını kod tarafında modelleyerek,nesneler üstünde çalışmamıza olanak sağlayan ve bu sayede runtime tespit edebileceğimiz tip uyuşmazlığı gibi hataları compile time’da bulup düzeltmemize olanak sağlayan bir teknolojidir.

Linq ile örneğimize geçmeden önce bazı uyarılarda bulunmak istiyorum.Linq’de nesneler arası ilişkilerin doğru şekilde yorumlanabilmesi için her tabloda mutlaka primary key olmalıdır.Bununla birlikte veritabanı oluşturulurken ilişkilerin de belirlenmesi gerekmektedir.(İstenirse .net tarafında da  assocationlar belirlenebilir ama bu daha uğraştırıcı olacaktır.)

1-)İlk olarak veritabanımızı modelleyerek nesnelere çevireceğimiz bir context oluşturmalıyız.

2-)Oluşturulan contextin içerisine veritabanımızdaki tablolar seçilip sürüklenerek bırakıldığı zaman otomatik olarak classlarımız oluşturulacaktır.Entityler arası bağlantının otomatik olarak oluşması için sql server tarafında tablolar arası relationları tanımlamak gerekir.

3-)Contextimizi oluşturduktan sonra projemize yeni bir sınıf ekliyoruz.(KisiService) ve oraya metodumuzu yazıyoruz.Burada KisiTablomuzundan modellenen KisiTablosus sınıfımız üstünden veritabanımızda bulunan tüm kişileri bir kişiler listesinin içerisini atıyoruz.Burada dikkat edilmesi gereken önemli bir nokta listemizde eleman yok ise dönecek bir şey olmayacak ve programız hata verecektir.Biz bunu önlemek için kisiler listesinin elemanlarını kontrol ettik ve eğer boş ise null döndürdük.Aynı şekilde SQLdeki orderby kullanarakda listemizi Ada göre sıralamış olduk.

public static List<KisiTablosu> TumKisileriAl()

{

DataClassesDataContext ctx = new DataClassesDataContext();

var kisiler = from c in ctx.KisiTablosus orderby c.Ad ascending select c;

if (kisiler.Count() <= 0 || kisiler == null)

{

return null;

}

else

{

return kisiler.ToList();

}

}

4-) 3 üncü şıkta DataClassesDataContext ctx = new DataClassesDataContext(); diye bir tanımlama yaptık,bu tanımlama doğru olmakla beraber her işlemde yeni bir context oluşturmak zahmetli ve iç-içe geçebilecek sorgularımızda ekle-sil-düzenle işlemlerimizde sorunlara neden olabilmektedir.Bunu önlemek için ise yarattığımız contexti saklayıp sürekli bu var olan context üstünden işlem yapacağız.Bunun için datacontextimizle çalışacak partial bir class yazmamız lazım

5-) Artık var olan context üstünden çalışacağız.Bu sayede iç içe geçebilecek iş akışları olan noktalarda verilecek hataların önüne geçebiliriz.İstersek veritabanınındaki tek bir kişiye erişmek isteyebiliriz böyle bir durumda bir liste tanımlamak yerine sadece bir kişi nesnesi tanımlayıp bunu da dizi üstünde gereken işlemleri yaparak çekebiliriz.

public static KisiTablosu KisiDetayGetir(int KisiID)

{

DataClassesDataContext ctx = DataClassesDataContext.Current;

var kisidetay = from c in ctx.KisiTablosus where c.KisiID == KisiID select c;

return kisidetay.ToArray()[0];

}

6-)Yeni bir kayıt eklemek istediğimiz zaman ise öncelikle yeni bir entity(varlık)(Nesne örneği ya da varlık örneği) oluşturuyoruz.Daha entitymizin içindeki özelliklerle parametre olarak gönderdiğimiz özellik değerlerini eşitleyerek entitymizin içini dolduruyoruz.Eğer veritabanında değerimiz null olabilir ise ve biz bunun kod tarafındaki kontrolü yapmazsak veritabanına boş kayıt ekleyebiliriz.Dikkat edilmesi gereken bir diğer önemli nokta ise contextimizin hangi tablosunda ne iş yapacağımızı belirtmek            (ctx.KisiTablosus.InsertOnSubmit(kt)) ve bunları kaydetmek için (ctx.SubmitChanges()) değişiklikleri onaylamaktır.Aksi takdirde kaydımız veritabanına geçmeyecektir.

public static bool KisiEkle(string Ad, string soyad, string TCKimlik, string OgrenciNo, string Faks)

{

DataClassesDataContext ctx = DataClassesDataContext.Current;

KisiTablosu kt = new KisiTablosu();

kt.Ad = Ad;

kt.Soyad = soyad;

kt.TCKimlikNo = TCKimlik;

kt.OgrenciNo = OgrenciNo;

if(!string.IsNullOrEmpty(Faks))

{

kt.Faks = Faks;

}

ctx.KisiTablosus.InsertOnSubmit(kt);

ctx.SubmitChanges();

return true;

}

7-)Peki BLL namespace içine aldığımız bu kişi classımızı ve burada yazdığımız metotları kod tarafında nasıl kullanacağız? Bu sorunun cevabı da gayet basit.

Örnek olarak 3 şıkta belirtilen TumKisileriAl metodunu bir object data source atıp bunuda bir gridviewe databind ettiğimiz zaman veritabanındaki tüm kişileri çekmiş olacağız

Benzer şekilde ekleme metodumuzu ise form tarafında bir buttonun click eventi içinde çağırabiliriz.

protected void btnEkle_Click(object sender, EventArgs e)

{

BLL.KisiService.KisiEkle(txtAd.Text, txtSoyad.Text, txtTCKimlik.Text, txtogrNo.Text, txtFaks.Text);

GridView1.DataBind();

}

8-)Var olan bir kaydı güncellemek için ise önce entity bulmalıyız.(Eklerken yeni bir entity oluşturmuştuk,burada var olan bir entity üstünde işlem yapacağız).Bir listedeki ilk entitymize ulaşmak için aşağıdaki gibi kisi.First() yardımı ile ulaşabiliriz.Burada entitymizi bulup değerleri atadıktan sonra tek yapmamız gereken context üstündeki değişikliği kabul etmektir.(ctx.SubmitChanges() komutu ile )

public static bool KisiGuncelle(int KisiID, string Ad, string soyad, string TCKimlik, string OgrenciNo, string Faks)

{

DataClassesDataContext ctx = DataClassesDataContext.Current;

var kisi = from c in ctx.KisiTablosus where c.KisiID == KisiID select c;

KisiTablosu kt = kisi.First();

kt.Ad = Ad;

kt.Soyad = soyad;

kt.TCKimlikNo = TCKimlik;

kt.OgrenciNo = OgrenciNo;

if (!string.IsNullOrEmpty(Faks))

{

kt.Faks = Faks;

}

ctx.SubmitChanges();

return true;

}

9-)Bir entity silmek için de aşağıdaki kod kullanılabilir.Yalnız entity silirken dikkat edilmesi gereken nokta ilişkilerdir.Örnek olarak bir kişinin telefonlarını silmeden kişiyi direkt olarak silmeye kalkışılırsa hata verilecektir.Bu yüzden önce kişiye ait telefon varsa silinmeli daha sonra kişi silinmelidir.(bunu ilerleyen şıklarda daha detaylı anlatacağım).

public static bool KisiSil(int KisiID)

{

DataClassesDataContext ctx = DataClassesDataContext.Current;

var kisi = from c in ctx.KisiTablosus where c.KisiID == KisiID select c;

ctx.KisiTablosus.DeleteOnSubmit(kisi.First());

ctx.SubmitChanges();

return true;

}

10-)Join Yapısı ile tabloları birbirine bağlayabiliriz.Bu bizim Sql de kullandığımız inner join yapısının linq daki karşılığıdır.Bu sayede primary key ve foreign keyleri linq üzerinde kullanabiliyoruz.

public static List<TelefonTablosu> KisiTelefonlar()

{

DataClassesDataContext ctx = new DataClassesDataContext();

var telefonlar = from c in ctx.TelefonTablosus

join e in ctx.KisiTablosus on c.KisiID equals e.KisiID

select c;

return telefonlar.ToList();

}

11-)Peki ilişkili tabloları bağladık.Ama bir kişiyi sildiğimizde bu kişiye ait telefon tablosundaki tüm kayıtları silmek istiyoruz.Bunuda aşağıdaki kodlar yardımıyla yapabilirsiniz.Birinci Kisiye AitTelefonlar metodu ile kişiye ait tüm telefonları bir listeye attık.Daha sonra kişisil metodumuzun içerisinde KisiyeAitTelefonlar metodunu çağırdık.Dönen listedeki telefonları bir döngü yardımı ile sildik.Daha sonra ise kişiyi silmiş olduk.

public static List<TelefonTablosu> KisiyeAitTelefonlar(int KisiID)

{

DataClassesDataContext ctx = DataClassesDataContext.Current;

var telefonlar = from c in ctx.TelefonTablosus where c.KisiID == KisiID select c;

if (telefonlar.Count() <= 0)

{

return null;

}

else

{

return telefonlar.ToList();

}

}

public static bool KisiSil(int KisiID)

{

DataClassesDataContext ctx = DataClassesDataContext.Current;

List<TelefonTablosu> t = BLL.KisiService.KisiyeAitTelefonlar(KisiID);

if (t != null)

{

foreach (var i in t)

{

ctx.TelefonTablosus.DeleteOnSubmit(i);

ctx.SubmitChanges();

}

}

var kisi = from c in ctx.KisiTablosus where c.KisiID == KisiID select c;

ctx.KisiTablosus.DeleteOnSubmit(kisi.First());

ctx.SubmitChanges();

return true;

}

}

12-)Linq sql de bahsetmek istediğim önemli nokta ise lamda expressionlar ki bunlar arama ekranları tasarlarken oldukça faydalı olacaktır.Burada önce bir sorgu oluşturup kayıtlarımızı çekiyoruz.Daha sonra çekilen kayıtlar üstünden parametrelerimizin değerlerine göre eleme işlemi yapıyoruz.Yani Birinci adımda kişitablosundaki tüm kayıtları aldık.Gelen ad parametresinde a harfi var diyelim,adında a olmayanları listeden çıkarmış olduk.Burada d.Ad.Contains(Ad),kısmı sql deki like %…% gibi çalışmaktadır.Yani kaydın herhangi bir yerinde aranılan harf varsa getirmektedir.Form tarafında ise aşağıdaki sorguyu bir object datasource ile gridview bağlanırsa,sizin kod olarak yapmanız gereken tek şey bir buttonun click eventine GridView1.DataBind() kodunu yazmaktır.Bu sayede siz parametrelerinizi girip ara bastığınız anda işlemleriniz yapılacaktır

Not:IQueryable<KisiTablosu> k = from c in ctx.KisiTablosus orderby c.Ad select c; dediğimiz anda veritabanında kisitablosundaki tüm kayıtları almış durumdadır.Yani sorgumuz otomatik olarak execute edilmiş durumdadır.Ad,soyad,ogrencino parametreleri her adımda sorgu execute edilecek ve liste daralacaktır.

public static List<KisiTablosu> KisiAra(string Ad, string soyad,string OgrenciNo)

{

DataClassesDataContext ctx = DataClassesDataContext.Current;

IQueryable<KisiTablosu> k = from c in ctx.KisiTablosus orderby c.Ad select c;

if (!string.IsNullOrEmpty(Ad))

{

k=k.Where(d=>d.Ad.Contains(Ad));

}

if (!string.IsNullOrEmpty(soyad))

{

k=k.Where(d=>d.Soyad.Contains(soyad));

}

if (!string.IsNullOrEmpty(OgrenciNo))

{

k=k.Where(d=>d.OgrenciNo==OgrenciNo);

}

if (k.Count() <= 0)

{

return null;

}

else

{

return k.ToList();

}

}

13-)

public static int YasToplam()

{

DataClassesDataContext ctx = DataClassesDataContext.Context;

var q = (from c in ctx.CalisanDetays select c).Sum(d=>d.Yas);

return q.Value;

}

Bu yazı .NET kategorisine gönderilmiş. Kalıcı bağlantıyı yer imlerinize ekleyin.

LINQ to SQL için 1 cevap

  1. mehmet kaskaya der ki:

    konunun örnek kodlarını bir liste yada döküman olarak ekleyebilirmisiniz..
    acıkcası cok karman çorman bir makale olmuşş..

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Şu HTML etiketlerini ve özelliklerini kullanabilirsiniz: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>