Bu site emekli olmuştur. Arşiv amaçlı olarak BT AKADEMİ sponsorluğunda yayın hayatına devam etmektedir.




C#nedir?com
 
YAZAR HAKKINDA
Sefer Algan
Sefer Algan
http://www.seferalgan.com
İletişme geçmek için tıklayın.
71 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler:  ADO.NET/SQL Sefer Algan
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : Başlangıç
Kategori : ADO.NET/SQL
Yayınlanma Tarihi : 20.7.2003
Okunma Sayısı : 51933
Yorum Sayısı : 1     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
Silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 23.11.2024
Turhal Temizer
Mac OS/X Removing CUDA 23.11.2024
Burak Selim Şenyurt
Rust ile ECS Yaklaşımını Anlamak 23.11.2024
Burak Selim Şenyurt
Birlikte Rust Öğrenelim Serisi 23.11.2024
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
DataSet'teki Tablolar Arasında İlişki Kurma(DataRelation)
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon

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.


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.

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.


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.

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);
    }
}



Ö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.

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
  • Yazılan Yorumlar
  • Yorum Yaz
NİS
11
2012
Merhaba; Hocam makalenizde Sondan 12'nci satırda "for" döngüsüne alıyorsunuz şartınız yazmıyo. Neye göre şart veriyosunuz. Kod galiba eksil kalmış.. Yazarsanız sevinirim. iyi çalışmalar.
Sayfalar : 1 
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • 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