|  | 
        
            | 
                    
                        | DataSet'teki Tablolar Arasında İlişki Kurma(DataRelation) |  |  
                        | 
	
    
		
            | Gönderiliyor lütfen bekleyin... | 
 |  | 
        
            | Bu makalede veritabanı ile bağlantısız bir biçimde çalışmamızı sağlayan DataSet 
  sınıfının Relations koleksiyonundan bahsedeceğiz. 
  .NET ile birlikte veriye erişim modelinde büyük ölçüde değişiklikler olmuştur. 
  Bütün bu değişikliklerin temelinde yatan neden veriye bağlantısız(disconnected) 
  bir şekilde erişme modelinin gerçekleştirilmesidir. .NET Framework içerisinde 
  veriye erişmek için sunulan arayüzlerin tamamı ADO.NET kütüphanesi şeklinde 
  anılmaktadır. ADO.NET ile veriye(veritabanı, XML) erişmek için iki metot kullanılabilir.
 
 1 - Bağlantılı Erişim : Bu yöntem eski ADO versiyonunda da kullanılan 
  yöntemdir. Bu metotta kullanıcı veritabanına bağlantı sağlar ve istediği sorguyu 
  çalıştırır. Sorgu sonucunda geri döndürülen veriler uygulamanın ihtiyacına göre 
  kullanılır. Veritabanına açılan bağlantı herhangi bir nedenden dolayı kesilirse 
  kullanıcının yeni sorgular yapması mümkün değildir. Bu yüzden veri tabanı bağlantısının 
  mümkün oılduğunca hızlı bir şekilde kullanılması gerekir.
 
 2 - Bağlantısız Erişim : Bu yöntem ADO.NET ile birlikte kullanılmaya 
  başlanmıştır. ADO.NET kütüphanesindeki çeşitli sınıflar yardımıyla bir veritabanındaki 
  istenilen tablodaki kayıtların tamamı istemcinin hafızasına alınır ve veritabanına 
  olan bağlantı kesilse bile istemci verilerle oynayabilir. Tabi veritabanı bağlantısı 
  kesildiği anda hafızadaki verileri veritabanına güncellemek mümkün değildir.(Güncelleme 
  için yeni bir bağlantının açılması gerekir) Bu yöntemle istemcinin hafızasında, 
  veritabanındaki tabloların resmen bir modeli oluşturulur. DataSet isimli sınıf 
  ile hafızadaki bu verilere sistematik bir şekilde erişmek mümkündür. Üstelik 
  hafızadaki bu veriler içinde çeşitli kompleks işlemler bile yapılabilmektedir. 
  Bu işlemlerden en önemlisi DataSet içindeki tablolar arasında ilişki kurmak 
  ve gerektiğinde bu ilişkiye dayanarak çeşitli sorgular yapmaktır. Bu yazının 
  ana konusu DataSet'teki tablolar arasında nasıl ilişki kurulacağını göstermektir. 
  Ancak hatırlatma olması açısından DataSet ile yakından ilişkili olan diğer yapılarıda 
  aktarmakta fayda görüyorum.
 
 DataSet Nesneleri
 
 DataSet nesnesi herhangi bir veri kaynağı ile ilişkilendirilmiş veri kümesini 
  temsil eder. Bu veri kaynağı bir veritabanı olacağı gibi XML formatlı bir kaynakta 
  olabilir. Nitekim DataSet nesnesinde tutulan veriler hafızada XML formatında 
  tutulmaktadır. DataSet içindeki veriler aynen veri tabanında olduğu gibi tablolar 
  şeklinde saklanır. Yani bir DataSet nesnesi bir yada birden fazla tablo barındırabilir. 
  DataSet'in yapısındaki tablolar DataTable isimli sınıfla temsil edilir. 
  Bu da DataSet'in DataTable türünden nesneleri olan bir kolekesiyona sahip olduğunu 
  gösterir. Bu koleksiyonun adı Tables' dır. Tables koleksiyonun Add() 
  ve Remove() metotları kullanılarak DataSet'e yeni tablo eklenip çıkarılabilir. 
  Tables koleksiyonundaki tablolara indeksleyici yardımıyla erişilebilir. İndeksleyincinin 
  parametresi tablonun ismi olabileceği gibi tablonun DataSet'teki sıra numarası 
  da olabilir.
 
 Her bir DataTable nesnesinin Rows ve Columns koleksiyonu bulunmaktadır. 
  Rows koleksiyonu DataTable'daki kayıtların kümesidir. Bu kümedeki her bir kayıt 
  ise DataRow isimli sınıfla temsil edilir. Bir kayıttaki veriler sütunlara 
  ayrılmıştır. Bir kayıt birden fazla sütundan oluşmuştur. Dolayısıyla her bir 
  kaydın ilgili sütununa erişmek için DataRow sınıfındaki indeksleyici kullanılır. 
  DataTable'da olduğu gibi indeksleyicinin parametresi sütunun adı yada sıra numarası 
  olabilir.
 
 DataSet nesnesinde veri ile direkt ilişkili olan bu nesnelerin yanı sıra ilişkisel 
  veri tabanı modelinin gerektirdiği yapıları barındırmak içinde çeşitli sınıflar 
  vardır. Bu sınıflardan en önemlisi DataRelation ve Constraint 
  sınıfıdır. İki tür Constraint(kısıt) sınıfı vardır. Bunlar UniqueConstraint 
  ve ForeignKeyConstraint sınıflarıdır. Constraint sınıfları temel olarak 
  verinin tablolara yerleştirilme kurallarını belirler. Örneğin UniqueConstraint 
  tablodaki bir kaydın tekil olmasını sağlarken, ForeignKeyConstraint sınıfı birbirleriyle 
  ilişkili tablolardan birinde meydana gelen değişikliğin diğerinde nasıl bir 
  etki yaratacağını belirler. DataTable nesnelerinin Constraints isimli koleksiyonuna 
  oluşturulan bu Constraint nesneleri aktarılarak kısıtların çalıştırılması sağlanır. 
  Dikkat edilmesi gereken nokta kısıtların çalışması için DataSet'in EnforceConstraints 
  özelliğinin true olması gerektiğidir. Diğer bir önemli sınıf ise DataRelation 
  sınıfıdır. Bu yazıda DataRelation detaylı bir şekilde anlatılacaktır. Bundan 
  sonraki yazımda ise Constraint sınıfları üzerinde duracağım.
 
 Yukarıda bahsi geçen bütün sınıflar verinin hafızada modellenmesi için gerekli 
  olan sınıflardır. Bir eksikliğin farkına varmış olmalısınız! Evet, değinmediğim 
  diğer önemli yapı DataAdapter sınıfıdır. DataAdapter bir DataSet'in yada 
  DataTable' ın içini doldurmak için veri kaynağı ile bağlantı kurar. Bu işlemi 
  yapan DataAdapter sınıfının Fill() metodudur. Bu metot parametre olarak bir 
  DataSet nesnesi alabileceği gibi DataTable nesnesi de olabilir. Eğer paramatre 
  bir DataSet nesnesi ise DataSet nesnesi içinde yeni bir DataTable nesnesi oluşturulur 
  ve veriler bu nesneye aktarılır. Veri kaynağına DataAdapter ile erişirken dikkat 
  etmemiz gereken önemli bir nokta var : Her DataAdapter nesnesi ile ancak bir 
  DataTable nesnesi oluşturulabilir. Dolayısıyla birden fazla tablo içeren DataSet 
  nesneleri ile çalışmak için birden fazla DataAdapter nesnesi oluşturmalıyız. 
  DataSet içinde yapılan değşikliklerin orjinal veri kaynağında güncellenmesi 
  içinde DataAdapter kullanılır. DataAdapter'in güncellenen verileri düzgün bir 
  biçimde ele alabilmesi için UpdateCommand, InsertCommand ve DeleteCommand gibi 
  özelliklerinin belirtilmesi gerekir. Command nesneleri bir SQL dizgesi 
  ve Connection nesnesi ile kurulur.
 
 DataRelation Sınıf
 
 İlişkisel veritabanı sistemlerinin en öenmli anahtar konusu tablolar arasında 
  ilişki kurup bu ilişkiyi kullanarak çeşitli sorgular yapmaktır. Tablolar arasındaki 
  ilişki, bildiğimiz en popüler veritabanı yönetim sistemlerinde görsel bir şekilde 
  tasarlanabilmektedir. Peki DataSet'teki tablolar arasındaki bu buna benzer bir 
  ilişkiyi programlama yolu ile bizler nasıl oluşturabiliriz? Bu sorunun cevabını 
  vermeden önce tablolar arasındaki ilişkinin ne demek olduğuna açıklık getirelim. 
  SQL Server 2000 ile birlikte otomatik olarak kurulan Northwind veritabanını 
  ele alalım. Bu veritabanında Customers(Müşteriler) ve Orders(Siparişler) isimli 
  iki tablo bulunmakta. Bu tabloların ortak özelliği her iki tabloda da aynı veriyi 
  temsil eden sütunların bulunmasıdır. Bu sayede Orders tablosundaki siparişlerin 
  hangi müşteriye ait olduğu saptanmaktadır. Tablolar arasındaki bu ilişkiyi sağlayan 
  sütun CustomerID isimli sütundur. Custmers tablosundaki bir kayda karşılık Orders 
  tablosunda birden fazla kayıt bulunmasından daha doğal bir durum olamaz. Çünkü 
  bir müşteri farklı zamanlarda aynı kimlikle birden fazla alışveriş yapmış olabilir. 
  Eğer DataSet içine ekleyeceğimiz bu iki tablo arasındaki ilişkiyi yine DataSet 
  içinde barındırabilirsek herhangi bir müşteriye ait toplam alışveriş miktarını 
  elde etmemiz çok kolay olacaktır. Söz konusu ilişkiyi kurmak için DataRelation 
  sınfı kullanılır. Peki DataRelation sınıfı nasıl oluşturulur?
 
 Bir DataRelation nesnesinin iki ana üyesi vardır. Bunlar ParantColumn ve ChildColumn'dur. 
  Yukarıda bahsettiğim Müşteri ve Sipariş ilşikisinde ParentColumn, Customers 
  tablosundaki CustomerID sütunudur. ChildColumn ise Orders tablosundaki CustomerID 
  sütunudur. Buna göre bir DataRelation nesnesi aşağıdaki gibi oluşturulabilir.
 
 
 
 
   
  Yukarıda tanımlanan 
  ilişkinin anlamı şudur : Her bir müşterinin çok sayıda siparişi bulunmaktadır. 
  Bu ilişkiden faydalanarak her bir Müşteri kaydına ait Child kayıtları elde etmek 
  mümkündür. Bu kayıtları elde etmek için DataRow sınıfının GetChildRows() 
  metodu kullanılmaktadır. Aynı şekilde Orders tablosundaki her siparişin hangi 
  müşteriye ait olduğunu temsil eden Parent Row kaydını yine DataRow sınıfının 
  GetParentRow() isimli metodu ile elde edebiliriz. Tabi bütün bu metotların 
  kullanımının geçerli olması için DataSet'in bu ilişkiden haberi olması gerekir. 
  DataSet nesnesini bu ilişkiden haberdar etmek için oluşturulan bu DataRelation 
  nesnesi DataSet'in Relations koleksiyonuna aşağıdaki gibi eklenmelidir. 
    | DataColumn 
        parent = ds.Tables[0].Columns["CustomerID"]; DataColumn child = ds.Tables[1].Columns["CustomerID"];
 
 DataRelation dr = new DataRelation("Dr1",parent,child); 
        //İlk parametre ilişkinin adını belirtir.
 
 
 |  
 
 
 
   
   
    | DataSetNesnesi.Relations.Add(dr); 
 
 |  Aşağıdaki örnek uygulamada bir DataSet'in farklı iki tablo ile doldurulması 
  ve bu iki tablo arasındaki ilişkiye dayanarak ne şekilde sorgu yapılabileceği 
  gösterilmiştir. Bir konsol uygulaması olan örneğimizde konsoldan girilen bir 
  müşteriye ait siparişlerin tek tek tutarı ve toplam bedeli ekrana yazdırılmaktadır.
 
 Not : Temel DataSet nesnelerinden olan DataColumn, DataRow ve DataTable sınıflarının 
  kullanımını bildiğiniz varsayıldığı için bu sınıfların kullanımı detaylı bir 
  şekilde anlatılmamıştır.
 
 
 
   
  Örneği derleyip 
  çalıştırdığınızda müşteri kimliği olarak "QUICK" girdiğinizde ilgili 
  müşteriye ati siparişlerin tutarı ekrana yazdırılacaktır. 
    | using 
        System; using System.Data.SqlClient;
 using System.Data;
 using System.Data.Common;
 
 class 
        DataRelationOrnek
 {
 static void 
        Main(string[] args)
 {
 string 
        kaynak="server=algans;uid=sa; pwd=; database=Northwind";
 
 SqlConnection 
        con = new SqlConnection(kaynak);
 
 SqlDataAdapter 
        adp1 = new SqlDataAdapter("select * 
        from Customers",con);
 
 SqlDataAdapter 
        adp2 = new SqlDataAdapter("select * 
        from Orders",new SqlConnection(kaynak));
 
 DataSet 
        ds = new DataSet("ds1");
 
 DataTable 
        dtnew = new DataTable("Yeni Tablo");
 
 adp1.Fill(ds);
 adp2.Fill(dtnew);
 
 ds.Tables.Add(dtnew);
 
 DataColumn 
        parent = ds.Tables[0].Columns["CustomerID"];
 DataColumn 
        child = ds.Tables[1].Columns["CustomerID"];
 
 DataRelation 
        dr = new DataRelation("Dr1",parent,child);
 
 ds.Relations.Add(dr);
 
 DataRow[] 
        childrows = new DataRow[50];
 
 Console.Write("Müsteri 
        kodu giriniz : ");
 
 string 
        ad = Console.ReadLine();
 
 for(int 
        i=0; i
                          if(ds.Tables[0].Rows[i]["CustomerID"].ToString() 
        == ad.ToUpper())
 childrows 
        = ds.Tables[0].Rows[i].GetChildRows(dr);
 
 Console.WriteLine("Alisveris 
        Tutarlari");
 
 double 
        total = 0;
 
 foreach(DataRow 
        drs in childrows)
 {
 Console.WriteLine(drs["Freight"]);
 total 
        = total + Double.Parse(drs["Freight"].ToString());
 }
 
 Console.WriteLine("Toplam 
        : " + total);
 }
 }
 
 
 
 
 |  
 ADO.NET ile ilgili bir sonraki yazımda Constraint(kısıt) sınıflarından bahsedeceğim.
 
 
 
                Makale:DataSet'teki Tablolar Arasında İlişki Kurma(DataRelation) ADO.NET ve SQL Sefer Algan
 | 
        
            |  | 
        
            |  | 
        
            | 
                    
                        
                            
                        
                            Eklenen Son 10 
                            Bu Konuda Geçmiş 10 
                        
                            Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
                         
                            Son Eklenen 10 Makale Yükleniyor
                         
                            Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
                         | 
        
            |  |