Tablolar Arası İlişkiler - DataRelation Sınıfı
- Memik Yanık
- 13.671
- Başlangıç
- 10 Nisan 2009
Bu makalede 2004 yılında yayınlanan ilk C# kitabımda tablolar arası ilişkilerin anlatıldığı sayfaları küçük eklemelerle sizinle paylaşacağım.
Bu makalede 2004 yılında yayınlanan ilk C# kitabımda tablolar arası ilişkilerin anlatıldığı sayfaları küçük eklemelerle sizinle paylaşacağım.
Önce biraz önbilgi:
Tablolar arası ilişki kurmayı ilk kez 1993 yılında Clipper kitabını yazarken anlatmıştım. 1993 yılından 2003'te yazdığım .NET uyumlu ilk Visual Basic kitabıma gelene kadar sayısız kez tablolar arası ilişkileri anlattım. İyi mi anlattım, kötü mü bilemem ama sayısız kez tablolar arası ilişkilerden söz ettim. .NET Framework uyumlu ilk Visual Basic kitabımda tablolar arası ilişkileri anlatmak için hazırladığım metni 2004 yılı başında aynen alıp küçük değişikliklerle yani aynı cümlelerle ilk C# kitabımda kullandım. Elim kırılaydı da .NET uyumlu ilk Visual Basic kitabımda kullandığım metni 2004 yılında yayınlanan ilk C# kitabımda kullanmayaydım. Çünkü mesleğinin zirvesinde bulunan 2 yerli yazar beni DataRelation sınıfı hakkında yazdıklarımdan dolayı suçladı ve dediler ki 'sen bizim kitaptan çalıntı yapmadan mümkünü yok .NET Framework ile gelen DataRelation sınıfından haberdar olamazsın'. Ben de kendilerine yapmayın etmeyin, siz daha bilgisayar nedir bilmezken benim dergilerde programcılık konulu yazılarım yayınlanıyordu. Ötesi 1994 ve 1995 yıllarında yazdığım ilk 3 kitabın hepsi veritabanı konuluydu. Yani tablolar arası ilişki nedir bilmem gerekir dedim ama dinletemedim.
Bu makalede 2004 yılında yayınlanan ilk C# kitabımda tablolar arası ilişkilerin anlatıldığı sayfaları küçük eklemelerle sizinle paylaşacağım. Bu arada dikkatinize şunu sunmak istiyorum: Bu metinde tablolar arası ilişkileri anlatırken yalnızca ve yalnızca 2 satır(yazı ile iki) kod yazdığımı bilmenizi isterim. Bu arada sizden bir isteğim var:Ne olur şartlarınızı zorlayınız beni çalıntı yapmakla suçlayan yazarların kitaplarından üçer beşer adet satın alın. Belki bu sayede Memik Yanık'ı suçlamaktan vazgeçerler.
Daha önce(yani C# kitabımın daha önceki sayfalarında) SQL Server veritabanları hakkında bilgi verilen bölümde tablolar arası ilişkinin nasıl kurulduğu anlatılmıştı(yani mesleğinin zirvesindekilere göre Memik Yanık, C# uygulamasından bağımsız olarak SQL Server veritabanlarının tabloları arasında ilişki kurmayı bilebilir ama aynı ilişkiyi C# uygulamasında DataRelation sınıfıyla kurmayı çalıntı yapmadan bilemez). Bu makalede tablolar arası ilişkilerin C# projeleri dahilinde nasıl kullanıldığını anlatacağım. Bu amaçla yeni bir proje hazırladım ve forma bir SqlConnection ve 2 SqlDataAdapter nesnesi yerleştirdim. Aşağıda verilen ekran görüntüsü Memik Yanık'ın kitabının çalıntı yapmakla suçlandığı sayfalarında bulunmaktadır. Yani bazılarına göre Memik Yanık başka kitaplardan çalıntı yapmadan forma SqlConnection ve SqlDataAdapter nesnelerini yerleştirmeyi akıl edemez.
SqlConnection nesnesi ile ilgilendiğim SQL Server veritabanına bağlandıktan sonra 1. SqlDataAdapter nesnesi için aşağıda verdiğim SQL kodunu hazırladım. 'SqlDataAdapter1' nesnesinin SelectCommand özelliğine aktarılan bu SQL kodu sayesinde 'Hesaplar' tablosundaki bütün kayıtlara erişim sağlanmış olunur. Tabii birileri ortaya çıkıp Data Adapter Configuration Wizard'dan yararlanmayı ilk ben akıl ettim, dolayısıyla bu Wizard'dan bir tek ben yararlanabilirim derse hiç şaşırmamak gerekir.
Tablolar arası ilişkiler söz konusu olduğu zaman tablolardan birisi Master, diğer Detail olarak değerlendirilmektedir. Tablolar arası ilişkiler hakkında bilgi verirken kullandığım 'Hesaplar' tablosu master ve 'islemler' tablosu ise detail olacak. Bu Master ve Detail kavramlarını 1996 yılında ilk Delphi kitabımı yazarken de kullanmıştım. Madem ilk Türkçe Delphi kitabını Memik Yanık yazdı, aralarında ilişki kurulacak tabloları Master ve Detail olarak adlandırmak Memik Yanık için suç olmamalıdır. Olmamalıdır diyorum ama oluyor. Çünkü Memik Yanık'ın ilk C# kitabının bu ekran görüntüsünün yer aldığı sayfadan dolayıda çalıntı yapmakla suçlanmıştır. Ötesi bu şikayet prof unvanlı bir öğretim üyesi tarafından yerinde görülmüştür. Ankara'da seçkin bir üniversitenin prof unvanlı bu öğretim üyesine Türkiye'nin bilişim alanındaki en eski derneğin yönetim kuruluna kadar yükselmiş bilgisayar mühendisinin katıldığını belirtmek gerekir.
2. DataAdapter nesnesi ile veritabanındaki 'islemler' tablosunun kayıtlarını elde etmek istediğim için aşağıda verdiğim SQL kodunu yazdım. SQL Server veritabanları hakkında bilgi verilen bölümde 'Hesaplar' tablosu ile 'islemler' tablosu arasında bire-çok ilişki kurmuş ve bu ilişkiye 'iliski_1' adını vermiştim. Nesne adı benzerliğinden dolayı suçlanmamak için sizler bu ilişkiye 'odun_1' veya 'tomruk_1' gibi bir ad verebilirsiniz.
Forma bu nesneleri yerleştirdikten sonra SqlDataAdapter1 nesnesi seçili iken Properties penceresindeki Generate Dataset linkini tıklayıp aşağıda verdiğim diyalog kutusunun ekrana gelmesini sağladım. Her 2 SqlDataAdapter ile erişilen tabloların içeriklerini aynı Dataset içinde değerlendirmek istediğim için Generate Dataset diyalog kutusundaki Choose which table(s).. başlıklı liste kutusunda her 2 DataAdapter nesnesini de seçtim. Bu arada Generate DataSet diyalog kutusunu ekrana getirmeyi ilk akıl edenin Türkiye'de mesleğinin zirvesinde bir yazar olduğunu unutmamak gerek. Bu nedenle Properties penceresindeki Generate DataSet linkini tıklayıp ekrana Generate Dataset diyalog kutusunu getirmek suçtur, çalıntı yapmaktır.
Anlatılan şekilde veritabanındaki 'Hesaplar' ve 'islemler' tablolarının DataSet'te birer DataTable ile temsil edilmesi sağlandıktan sonra kod yazılarak bu DataTable nesneleri arasında ilişki kurulabilir. Konunun kolay anlaşılmasını sağlamak için öncelikle bu işlemi kod yazmadan grafiksel olarak yapacağım. Dataset'teki tabloların arasında ilişki kurmak istiyorsanız Properties penceresinde Dataset'in özellikleri listelenirken View Schema linkini tıklamalısınız.
Üzerinde çalıştığınız projede Toolbox'tan yararlanarak veya Properties penceresindeki Generate Dataset linkini tıklayarak(tabi bu durumda suç işlemeyi göz almış olursunuz) Dataset nesnesi hazırlamanız halinde 'xsd' uzantılı bir dosya hazırlanıp projeye dahil edilir. Projeye bu şekilde dahil edilen xsd uzantılı dosyayı Solution Explorer penceresinde görebilirsiniz.
xsd uzantılı dosyalarda Dataset nesnesi ile ilgili XML kodları veya Dataset'in şematik yapısı hakkında bilgi bulunmaktadır. Properties penceresinde View Schema linkini tıklamanız halinde söz konusu Dataset'e ait xsd dosyası açılır. Bu dosyayı açmak için Solution Explorer penceresinden yararlanabilirsiniz. Properties penceresinde View Schema linkini tıklayınca aşağıdaki gibi bir pencere açıldı.
Dataset'e ait 'xsd' uzantılı dosyanın açılmış halinin olduğu bu pencerede DataTable nesnelerinin şematik gösterimi bulunmaktadır. Bu gösterimi sağlayan ve geri planda hazırlanan XML kodlarını görmek istiyorsanız XML sekmesini tıklamanız yeterlidir.
Xsd uzantılı dosya içeriğinin görüntülendiği pencere aktif iken Toolbox'ta XML Schema adında bir sekme olmaktadır. Kod yazmadan Dataset'e ait pencerede şematik olarak tablolar arası ilişki kurmak istiyorsanız Relation kontrolünden yararlanmanız gerekir.
Toolbox'ta Relation kontrolünü Dataset'in şematik yapısında Detail olarak kullanılacak tablonun üzerine bırakırsanız ekrana aşağıda verilen Edit Relation diyalog kutusu gelir. Sanmayınız ki Edit Relation diyalog kutusunu ekrana getirmek her babayiğidin harcıdır. Eğer 2003 yılının sonunda direk mesleğin zirvesine yerleşen 2 yerli yazar C# kitabı yazıp yayınlamamış olsaydılar Türkler, Hintliler, Meksikalılar ve Ruslar vs Edit Relation diyalog kutusunu ekrana getirmeyi akıl edemezlerdi.
Bu diyalog kutusunda Relation kontrolü sayesinde kurulan ilişkinin özellikleri bulunmaktadır. Name metin kutusunun içeriğini değiştirip Relation nesnesine istediğiniz adı verebilirsiniz. İlişkiye vereceğiniz adın küfür veya argo kelime içermesi sizin hayrınıza olabilir. Anlatılan şekilde hazırlamış olduğum Relation nesnesine 'iliski1' adını verdim. Parent element başlıklı liste kutusunda Master tablo ve Child element başlıklı liste kutusunda ise Detail tablo seçilmektedir. SQL Server veritabanını hazırlarken bu tablolar arasında ilişki kurmuş ve bu ilişkiye 'iliski_1' adını vermiştim.
Tablolar arası ilişki bir alanın üzerinden kurulmaktadır. Master tabloda bu amaçla kullanılacak alanın Unique veya Primary key olarak indekslenmiş olması gerekir. Detail olarak kullanılan tabloda aynı içeriğe sahip birden fazla kayıt olabileceği için indeksin Primary key özellikli olmaması gerekir.
İlişkiyi her 2 tablodaki 'Hesap_kodu' alanı üzerinden kurmak istediğim için Key Fields ve Forigen Key Fields liste kutularında 'Hesap_kodu' alanını seçtim. Edit Relation diyalog kutusunda gerek duyduğunuz ayarlamaları yapıp diyalog kutusunu OK düğmesi ile kapatırÂsanız kurulan ilişki şema penceresinde grafiksel olarak işaret edilir.
Dataset'teki tabloların arasında kurduğunuz ilişkinin özelliklerini sonradan değiştirme gereğini duymanız halinde ilişkiye ait kısayol menüsünden Edit Relation komutunu verebilirsiniz. Tanımlamış olduğunuz ilişkiyi silmek istiyorsanız seçip Delete tuşuna basmanız yeterlidir.
Bu şekilde kod yazmadan 'Hesaplar' ve 'islemler' tabloları arasında 'Hesap_kodu' alanları üzerinden ilişki kurduktan sonra forma DataGrid nesnesi yerleştirip DataGrid nesnesinin DataSource özelliğine bu Dataset'in adını aktardım.
Tam bu noktada izninizle ek açıklama yapalım: Bilirsiniz dünyada üretilen bisikletlerin büyük bir yüzdesi 2 tekerleklidir. Benzer şekilde otomobillerin neredeyse tamamı 4 tekerleklidir. Şimdiye kadar ne GM ne Ford firması otomobil işine çok sonra giren Japon ve Koreli üreticileri '4 tekerlekli araba üretmeyi ilk biz akıl ettik, sizler 4 tekerlekli araba üretemezsiniz' diye dava etmediler. Programcılar ise veritabanından çektikleri verileri formların üzerinde kullanıcıya sunarken genellikle bir yani '1' DataGrid'den yararlanırlar. Ne var ki programcıların forma yalnızca 1(bir) DataGrid yerleştirmeleri Türkiye'de artık suçtur. Çünkü forma 1 DataGrid yerleştirme fikri yerli bir yazara aittir ve kimse bu fikirden yararlanamaz. Bence sizler forma buçuklu sayıda DataGrid yerleştirmelisiniz. Örneğin forma gereksin gerekmesin 3,5(üçbuçuk) sayıda form yerleştirin(!).
Daha önceki konulardan(yani C# kitabından...) bildiğiniz gibi SqlDataAdapter nesneleri ile erişilen tabloların içeriklerini Fill() metodu ile Dataset'e aktarmak gerekmektedir. Bu nedenle formun Load olayını temsil eden metodu aşağıdaki gibi düzenledim. İşte ilk C# kitabımda DataRelation sınıfı hakkında bilgi verirken yazdığım 2 satır kod. Yani bazılarına göre SqlDataAdapter sınıfının Fill() metodunu kullanmak çalıntı yapmaktır. Çünkü Fill() metodunu kullanmayı ilk kendileri akıl etmişlerdir.
Bu hazırlıklardan sonra proje çalıştırıldığı zaman DataGrid'de Dataset'eki mevcut DataTable nesneleri listelenir. Proje çalıştırıldığında bu DataTable nesnelerinden birisinin içeriğinin DataGrid'de görüntülenmesini istemiş olsaydım söz konusu DataTable nesnesinin adını DataGrid'in DataMember özelliğine aktarırdım. Bu arada bu kodu Visual Studion 2003 kullanarak yazdığımı belirrmek isterim.
Bu sırada Master özellikli 'Hesaplar' tablosunu tıklayınca aşağıdaki gibi bir sonuç aldım. Bu tablo başka tablo ile ilişkili olduğu için her kaydın önünde artı(+) işareti vardır. Hangi kaydın ilişkili tablodaki(burada islemler) ayrıntılarını görmek istiyorsanız o kaydın önündeki artı işaretini tıklamanız gerekir.
Aşağıda verilen ekran görüntüsünü tablodaki ilk kaydın satır başlığını tıkladıktan sona aldım. Kaydın satır başlığını tıklayınca tanımlanmış olan ilişkiyi temsil eden link görünür. Bu linki tıklarsanız 'Hesaplar' tablosundaki ilk kaydın(burada 06001) 'islemler' tablosundaki ayrıntıları DataGrid'de görüntülenir.
Bu sırada Grid'in sağ üst köşesindeki geriye ok seçeneğini tıklayıp Grid'de tekrar 'Master' tablodaki kayıtların listelenmesini sağlayabilirsiniz. Böylece istediğiniz kaydın ayrıntılarını kolayca aynı grid üzerinde görebilirsiniz.
Master ve Detail tabloların içeriklerini farklı DataGrid'lerde görüntüleyerek DataRelation nesnesini daha işlevsel yapabilirsiniz. Bu amaçla forma 2. bir DataGrid nesnesi yerleştirdim ve ilk DataGrid'in DataMember özelliğine Master tablo olarak kullandığım tablonun adını aktardım.
Forma yerleştirdim 2. DataGrid'in DataSource özelliğine aynı DataSet'in adını aktardıktan sonra DataMember özelliğine ise tanımladığım ilişki veya DataRelation nesnesinin adını aktardım. Properties penceresinde DataMember özelliğine ait liste kutusunda mevcut ilişkiler Master tablonun birer alt seçeneği olarak listelenmektedir.
Tam bu sırada Ankara'da bir üniversitenin bilgisayar mühendisliği bölümünde görev yapan prof unvanlı bir öğretim üyesinin ve Türkiye'nin bilişimle ilgili en eski derneğinin yönetim kurulu üyeliğine kadar yükselmiş bilgisayar mühendisinin Memik Yanık'ın ilk C# kitabının DataRelation sınıfı hakkında bilgi verilen bölümüyle ilgili olarak kurduğu cümleden sizleri mahrum bırakmamak için buraya alacağım:
'Tablolardan çekilen verilerin tek bir datagrid içerisinde gösterilmeye çalışılması'' Gördüğünüz gibi bu saygıdeğer bilim adamı Memik Yanık'ı kitabında veritabanındaki tablodan çektiği verileri tek (yani 1) DataGrid'de görüntülemekle suçlamaktadır. Bu bilim adamına kalırsa forma 1 tek DataGrid yerleştirmek yerli bir yazardan başka dünyada kimsenin aklına gelmez. Başka bir deyişle mesleğinin zirvesindeki yazarlara ve bu öğretim üyesine göre forma DataGrid'ler üçer beşer yerleştirilmelidir.
Bu ayarlamalardan sonra proje çalıştırıldığında ilk DataGrid'de master tablo olarak kullandığım 'Hesaplar' tablosunun içeriği görüntülenir. Formun alt kısmına yerleştirdiğim 2. DataGrid'de ise Master tabloda seçilen kaydın ilişkili tablodaki ayrıntı kayıtları listelendi. Madem aşağıda verilen ekran görüntüsü Memik Yanık'ın 2004 yılında yayınlanan ilk C# kitabından alındı Tablolardan çekilen verilerin tek bir datagrid içerisinde gösterilmeye çalışılması'' cümlesini yazan birisi prof unvanlı 3 bilgisayar mühendisi bu metni okuduklarına kimse kendilerini görmesin diye kaybolmak isterler mi bilinmez.
Bu ekran görüntüsünü aldığım sırada Master tabloda' Hesap_kodu' alanında '06001' bilgisi olan kayıt seçili olduğu için kurulan ilişki sayesinde Detail tablodaki Hesap_kodu alanında aynı bilgi olan kayıtlar listelenir. Bu sırada Master tabloda başka bir kaydın üstüne gitmeniz halinde formun alt kısmında görüntülenen kayıtlar kendiliğinden değişir. İzninizle bu metni bir cümle ile değerlendireceğim: 2004 yılı şartlarına yani henüz .NET hakkında programcılar yeterince bilgiye sahip değilken bu metin oldukça iyidir. Ancak 2009 yılına göre bu metin artık sıradandır.