Ana Sayfa > ADO.NET > Microsoft Visual Basic.NET ve ADO.NET ile SQL Server İşlemleri / 1

Microsoft Visual Basic.NET ve ADO.NET ile SQL Server İşlemleri / 1

30 Nisan 2010

Bu
dokumanda Microsoft .NET altyapısı ile sunulan veri erişim teknolojisi
ADO.NET’i detaylı olarak ele alıyor olacağız..

style=font-size:10.0pt;font-family:Wingdings>Ø      
Giriş

style=font-size:10.0pt;font-family:Wingdings>Ø      
ADO.NET
Nesneleri

style=font-size:10.0pt;font-family:Wingdings>Ø      
Bağlantı
Oluşturma

style=font-size:10.0pt;font-family:Wingdings>Ø      
Command ve
DataReader Nesneleri ile Çalışmak

style=font-size:10.0pt;font-family:Wingdings>Ø      
DataAdapter,
Data Set, Form ve Form Kontrolleri

style=font-size:10.0pt;font-family:Wingdings>Ø      
Verileri
Düzenlemek, Silmek ve Oluşturmak 

Bu
dokuman beş ana bölümden oluşmaktadır.

style=font-size:10.0pt;font-family:Verdana>-        
İlk olarak
ADO.NET’in yapısı hakkında genel bilgiler veriyor olacağım

style=font-size:10.0pt;font-family:Verdana>-        
Daha sonra SQL
Server veritabanına bağlantı oluşturma ve bu bağlantıyı güvenli hale getirme
konusunu ele alıyor olacağım

style=font-size:10.0pt;font-family:Verdana>-        
Read-Only,
forward-only veri erişimini detaylı olarak ele alarak, bu tür veri erişim
tekniğine dair pek çok örnek geliştireceğiz

style=font-size:10.0pt;font-family:Verdana>-        
Sonraki adımda
Windows Form uygulamalarında data set kullanımını ele alıyor olacağız. Windows
Form kontrollerine programatik olarak veri bağlama konusunda pek çok örnek
yapacağız. Aynı zamanda bu bölümde Parent-Child ilişkilerini ele alacağız.

style=font-size:10.0pt;font-family:Verdana>-        
Son olarak
Windows Form uygulamalarından SQL Server’da yer alan verilerin düzenlenmesini,
silinmesini ve yeni verilerin eklenmesini ele alıyor olacağız. 

1 – ADO.NET
Nesneleri

Her ne
kadar ADO.NET varsayılan olarak üç adet data provider sunuyor olsa da ben bu
dokumanda SQL Server 2000 ile ilgili işlemlerde kullanacağımız SQL Server Data
Provider’ı ele alıyor olacağım. SQL Server Provider’ı, System.Data.SQLClient
namespace’i aracılığıyla kullanabiliriz. SQL Server Provider’ı ile bize sunulan
ADO.NET nesnelerine erişebilmek için bu namespace’i aşağıdaki sözdizimi ile sınıfımıza
(Form, Modul, Class vb) dahil etmemiz gerekiyor; 

color:#333399>Imports System.Data.SqlClient 

Altı
temel ADO.NET nesne sınıfı vardır. Bu sınıflar; Connection, Command,
DataReader, DataAdapter, DataSet ve DataView sınıflarıdır.
Bu bölümde bu altı sınıfı ve bu sınıfların ADO.NET uygulamalarında sıklıkla
kullanacağınız en önemli özellik ve metodlarına odaklanıyor olacağız.

Connection
Sınıfı

Connection sınıfı
uygulamanızın bir veri kaynağında yer alan verileri okumasını ve veri kaynağına
ekleme yapabilmesini sağlar. Bu sınıfın SQL Data Provider ile bize sağladığı SqlConnection
nesnesini kullanarak sunucuya (sql server) NT veya SQL Server Authentication
mekanizmalarından birini kullanarak bağlanabiliriz. ConnectionString yapısı
ADO’da kullandığımız ConnectionString’lere oldukça benzemektedir. Ek olarak
bağlantıyı Open metodu ile açabiliyor, Close metodu ile kapatabiliyoruz. Bağlantı
kurma/kapama esnasında oluşan exception’ları yakalayabiliyor ve gerekli
işlemleri gerçekleştirebiliyoruz. Örneğin veri okunabilen bir backup sunucunuz
varsa, ana sunucuya bağlanılamadığı durumlarda uygulamanızın backup sunucusuna
bağlanarak işlem yapmasını kolayca sağlayabiliyoruz. Uygulamalarımız,
kullandığı Connection nesnelerini işleri bittiğinde mutlaka kapatmalıdırlar.

SqlConnection style=font-size:10.0pt;font-family:Verdana> nesnesinin ConnectionString özelliği
bağlantı oluşturulurken kullanılacak bağlantı satırını tanımlamanıza olanak
verir.  DataSource özelliği bağlantının kurulacağı SQL Server’ı, Database
özelliği SqlConnection nesnesinin erişeceği sunucuda çalışılacak
veritabanını, ConnectionTimeout özelliği uygulamanın SqlServer’dan yanıt
gelmesi için ne kadar bekleyeceğini (süre dolduğunda bir exception oluşturulur)
tanımlamanızı sağlar.  

Command
Sınıfı

Command
sınıfı sunucuya gönderilecek deyimleri barındırır. Bu deyimler, Select
ifadeleri olabilir, data manupulation ifadeleri olabilir veya sunucu üzerinde
yeni nesneler oluşturacak veya varolan nesneler üzerinde değişiklik yapan
ifadeler olabilir.

Bu
deyimleri sunucuya göndermek için Sql Server data provider tarafından sunulan SqlCommand
nesnesini kullanırız. SqlCommand nesnesinin üç önemli özelliği vardır. Bunlar;
Commandtext, CommandType ve Parameters özellikleridir. CommandText
özelliği T-SQL ifadesini, stored procedure adını veya tablo adını içerir. ADO.NET,
CommandText özelliğini varsayılan olarak T-Sql olarak tanımlamıştır. CommandType
özelliği üç değer alabilir: Text, StoredProcedure ve TableDirect.
CommandText özelliğinde bir Stored Procedure adı belirttiğimiz
durumlarda CommandType özelliğini StoredProcedure olarak, bir
veya daha fazla sayıdaki tablodan, tablo(lar)daki tüm sütun ve satırları
alacağımız durumlarda TableDirect belirtiriz. TableDirect ile
birden çok tablo kullanmak istediğimiz durumlarda tablo isimlerini virgül ile
ayırırız.

SqlCommand
nesnesinin Parameters özelliği bir kolleksiyondur. Parametreler, Stored
Procedure’ler, diğer veritabanı nesneleri ve T-SQL ifadeleri için dinamik
olarak argumanlar oluşturmakta kullanılır. Özellikle veritabanında veri ekleme
/ güncelleme işlemleri gerçekleştirdiğiniz durumlarda parametreler oldukça
faydalı olacaktır. Parametreleri aynı zamanda Stored Procedure’lerden output
parametrelerini almak ve Stored procedure’lerden değer döndürmek amacıyla
kullanabilirsiniz.

Command
nesnesi, farklı T-SQL işlemlerini gerçekleştirmek için çeşitli metodlar sunar. Örneğin
bir SELECT ifadesi ile bir DataReader nesnesini doldurmak için ExecuteReader
metodunu kullanabilirsiniz veya nesneler oluşturmak veya varolan nesnelerin
özelliklerini değiştirmek gibi geriye resultset döndürmeyen işlemler
için geriye sadece kaç kayıt etkilendiğini döndüren ExecuteNonQuery
metodunu kullanabiliriz. Command nesnesinin bir diğer metodu ExecuteScalar
ise geriye sonuç satırlarını değil, sorgu sonucunda oluşacak sonuç kümesinin
ilk satırının birinci sütunudur.

DataReader
Sınıfı

DataReader sınıfı
bir veri kaynağına read-only ve forward-only bağlantı imkanı sağlar. DataReader
sınıfından oluşturulan nesneler açık bağlantı kullanır. DataReader nesneleri
ile veri okuyabiliriz ancak veri ekleme/düzenleme işlemleri gerçekleştiremez,
sonuç kümesi içinde ileri-geri hareket edemeyiz. DataReader sınıfından
türetilen nesnelerin kullanımı, performansın, esneklikten daha önemli olduğu
durumlarda tercih edilebilir. Bunun nedeni her DataReader nesnesinin kendisine
özel bir Connection nesnesine gereksinim duymasıdır. Sunucu tarafında
istemcilerden açılabilecek maximum bağlantı sayısına ulaşıldığında,
istemcilerin yeni bir bağlantı oluşturabilmek için bağlantıyı açık tutan
DataReader nesnelerinden birinin bağlantısını kapatmasını beklemeleri
gerekecektir.

SQL Data
Provider tarafından sunulan SqlDataReader nesnesini kullanmak için SqlCommand
nesnesinin geriye bir sonuç kümesi döndüren ExecuteReader metodunu
kullanırız. DataReader ile açtığınız bağlantıyı kapatmanız, sunucu performansı
açısından önemlidir. Bağlantıyı Connection nesnesinin Close metodu
ile kapatabiliriz. RecordsAffected özelliği DataReader’ın seçtiği kayıt
sayısını döndürmektedir ancak hatasız bir değer ancak bağlantı kapatıldıktan
sonra elde edilebilmektedir. Eğer sorgunun çalıştırılması başarısızlıkla
sonuçlanırsa DataReader nesnesinin FieldCount özelliği 0 olarak
dönecektir.

Bir
DataReader nesnesi populate edildiken hemen sonra sonuç kümesinin birinci
satırına odaklanır. Birinci satırı okumak için DataReader nesnesinin Read
metodunu kullanırız. Read metodunu yeniden çalıştırarak bir sonraki
kayıda ulaşabiliriz. Son satıra ulaşıldığında, gidilecek bir sonraki satır
olmadığından Read metodu False değerini döner. Sütun değerlerini
GetInt32, GetString veya GetSqlDateTime gibi Get metodlarından herhangi
biri ile alabiliriz. Bu metod sütun değerlerini doğru veri türü formatlamasıyla
edinmemizi sağlar. (Örnek: Drd1.GetString(0) Drd1 adlı DataReader’da bulunulan
satırın birinci sütununun değerini string türünde dönecektir)

DataAdapter
Sınıfı

DataAdapter

sınıfı SQL Server veri kaynağı ile bir sonraki adımda inceleyeceğimiz DataSet
sınıfından türetilmiş nesneler arasında köprü görevi görür. DataAdapter
sınıfını kullanarak bir DataSet’i populate edebileceğimiz gibi, local bir
DataSet içindeki verileri SQL Server’daki veri ile senkronize edebilirsiniz. DataAdapter
sınıfı ADO.NET içindeki en temel sınıflardan biridir ve ADO.NET uygulamalarının
esnekliğini arttırmak amacıyla geliştirilmiştir. DataSet sınıfı kendisine
bağlı hiyerarşik bir yapısı olan nesneleri ile bağlantısız (disconnected) veri
erişim imkanı sunar. Bu nedenle DataAdapter sınıfı veri kaynağına sabit bir
bağlantı olmasına ihtiyaç duymaz ve veri sorgulama, güncelleme gibi işlemler
için anlık bağlantılar kurar.

SQL
Server Data Providerı bize SqlDataAdapter sınıfını sunar. SqlDataAdapter
nesnesini bir SqlConnection nesnesi ile bağlantılı olarak kullanmamız
gerekir. DataAdapter nesnesinin kullandığı SqlConnection nesnesi,
DataSet nesnesinde tutulan local veri ile sunucudaki veri arasında köprü görevi
görür.

Local bir
DataSet nesnesini populate etmek için DataAdapter nesnesinin Fill metodunu
kullanırız. Bu metodu kullanabilmek için DataAdapter nesnesi, açık bir
bağlantıya ihtiyaç duyar. Fill metodu çalıştktan sonra uygulamanız bağlantıyı
kapatabilir ve local DataSet nesnesinde barındırılan veri ile çalışmaya devam
edebilir.

SqlDataAdapter style=font-size:10.0pt;font-family:Verdana> sınıfı SQL Server üzerindeki
veriler üzerinde değişiklik yapabilmemizi sağlayan Update metodunu ve bu
metoda bağlı olaral UpdateCommand, DeleteCommand ve InsertCommand
nenelerini sunar. Bu özellikler için doğrudan T-SQL ifadeleri kullanabilir veya
stored procedure’leri kullanabilirsiniz. Bu işlemler için gerekli
parametreleri, InsertCommand, UpdateCommand ve DeleteCommand
özellikleri tarafından sunulan parameters özelliğini kullanarak
belirtiriz. Bu komutları çalıştırdığımızda değişiklikler local DataSet’te
yapılır. DataAdapter nesnesinin Update metodunu kullanarak local
DataSet’teki işlemleri, Sql Server üzerinde geçerli kılarız. 

SqlDataAdapter
nesnesi, veri kaynağı ve yerel dataset arasında optimistic concurency’i
destekler. Gerçekte ADO.NET pessimistic concurrency’i (işlem yapılırken
veritabanının işlemi yapan dışındaki kullanıcıların kullanımına karşı
kilitlenmesi) aktif tutmaz. Keyset cursor’lar ve bağlantılı recordset’ler
ADO.NET’in içinde yer almaz. Optimistic concurrency esnekliğin arttırılmasını
sağlarken local verideki güncellemelerin sunucuyla senkronizasyonu aşamasında
daha fazla dikkat gerektirir. Örneğin; siz son erişiminizi yaptıktan sonra
değişikliğe uğramış bir veriyi, local veri ile güncellemek istediğinizde bir
optimistic concurrency violation oluşacak ve bir exception oluşturulacaktır.

“
Optimistic ve pessimistic concurrency çok kullanıcılı platformlarda kullanılan
iki veri yönetim mekanizmasıdır. Pessimistic concurrency kullanılırken
kullanıcı veri üzerinde bir değişikliğe başladığı anda ilgili veri kaynağı
diğer kullanıcıların kullanımına karşı kilitlenir ve bu kilit işlem tamamlanana
kadar açılmaz. Optimistic concurrency’de ise bu tür bir kilitleme yapılmaz,
dolayısıyla siz bir veriye güncellemek üzere eriştiğinizde, siz
güncellemelerinizi kaydetmeden başka bir kullanıcı kendi güncellemelerini
kaydedebilir. ”

ADO.NET
optimistic concurrency violation’dan kaynaklanacak hataları önlemek için iki
teknik sunuyor. Birincisi RowUpdated eventi için bir prosedür
oluşturabilirsiniz. ADO.NET bu eventi sunucudaki verinin, değişiklik yapılmış
bir local dataset ile güncellenmesi talebi sonrasında oluşturur. RowUpdated
eventi ile hata oluşması durumunda yapılacak işlemleri her satır için
tanımlayabilirsiniz. İkinci yönetmde ise Update metodunu çalıştırmadan önce  SqlDataAdapter
nesnesinin ContinueUpdateOnError özelliğinin değerini True olarak
değiştirebilirsiniz. Bu sayede ADO.NET’in tüm gerçekleştirilebilir
güncellemeleri gerçekleştirmesini ve tüm hata mesajlarını local DataSet’e
yazmasını böylece daha sonra bu hatalarla ilgilenebilmemizi sağlarız.

DataSet
Sınıfı

DataSet
bellekte
yer alan, bir veya daha fazla sayıda tablo ve tablolar arasında ilişkiler
içerebilen bir nesnedir. DataSet’i bellekte oluşturulan bir veritabanı olarak
düşünebiliriz. DataSet nesnesi ve kendisine bağlı alt nesneler ADO.NET’in
temeli olan bağlantısız veri erişimi mimarisinin temel unsurudur. Aşağıdaki
grafik DataSet nesne modelini görüntülemektedir.

 

style=font-size:10.0pt;font-family:Verdana> src="http://www.yazgelistir.com/images/kadir/adonet/image001.gif">

Şekil 1:1 – DataSet Nesne Modeli

style=font-size:10.0pt;font-family:Verdana> 

Bir
DataSet içinde yer alan tablolar birer DataTable nesnesidir.. DataSet
içindeki tüm tabloların birleşimi ortaya DataTableCollection sınıfını
ortaya çıkarır. DataSet içinde yer alan tablolar, DataSet içindeki diğer
tablolar ile ilişki içinde olabilir. Bu, Northwind örnek veritabanının aynısını
bir DataSet içinde oluşturabileceğimiz anlamına geliyor. Klasik ADO’da yer alan
RecordSet sadece bir sonuç kümesi barındırabildiğinden bu tür bir yapı
oluşturma imkanımız yoktu.

Datatable style=font-size:10.0pt;font-family:Verdana> nesnesi iki temel yapıdan oluşur:
DataColumn ve DataRow nesneleri. DataTable nesnesindeki
sütunlar, DataTable nesnesinin şemasını oluşturan DataColumnCollection
nesnesini oluşturur. Örneğin her bir DataColumn nesnesi, ilgili sütunun kabul
edebileceği veri türünü belirler. DataTable nesneleri PrimaryKey özelliğini
kullanabilirler. Bu özelliği, bir veya daha fazla sayıda DataColumn nesnesi
içeren DataColumn dizisi ile tanımlayabilirsiniz. DataRowCollection
sınıfı DataTable içindeki tüm satırları içerir. DataTable içinde yeni
bir satır oluşturmak için NewRow metodunu çalıştırırız. Data sonra sütun
değerlerini belirtir ve yeni DataRowu DataTable nesnesinin DataRowCollection
nesnesine dahil ederiz.

ADO.NET
DataSet içindeki tablolar arasındaki ilişkiyi DataRelation nesnesi ile
sağlar. Bir DataSet nesnesi içindeki tüm DataRelation’lar DataRelationCollection
nesnesini oluşturur. Ek olarak Constraint sınıfını kullanarak
tablolar için yeni Constraintler tanımlayabilirsiniz. Bir Constraint nesnesi
ile unique veya foreign key constaintlerini tanımlayabilirsiniz. Bir DataRelation
nesnesi iki tablo arasında Parent-Child ilişkisini temsil eder. İki tablo
arasında bir DataRelation nesnesi oluşturduğunuzda ADO.NET otomatik olarak
child tabloda foreign key, parent tablodaki primary key alanında da unique
constrainti oluşturur. DataSet nesnesinin DataRelationCollection sınıfı
DataSet içindeki tüm DataRelation nesnelerini içerir. DataRelation
nesnelerinin üyelerine DataTable nesnesinin ChildRelations ve ParentRelations
özellikleri ile erişebilirsiniz.

Bir DataTable
nesnesinin DataRowCollection’ından bir DataRow silmek için
kullanabileceğimiz iki yöntem vardır. Birinci yöntem DataTable içindeki DataRow
nesnelerinde geçerli olacak Delete metodunun kullanımıdır. Bu metod,
DataRow nesnesinin RowState özelliğine Deleted değerini
verecektir ancak aslında satırı local tablodan silmiş olmayacaktır (Uygulamanız
silinmiş bir satırı DataRow nesnesinin RejectChanges metodunu kullanarak
geri getirebilir). Alternatif bir yöntem ise bir satır için Delete
metodunun uygulanmasıdır, bu sayede bu satır, AcceptChanges metodu
tarafından geri getirilemeyecektir.

İkinci
yöntem ise DataTable nesnesinin DataRowCollection nesnesinin Remove
metodunun kullanılmasıdır. Bu metod, silmek istediğiniz satırın indexini
belirtmenizi gerektirir. Index değeri 0dan başlar ve her kayıt için 1 artarak
devam eder. Bu yöntemin kullanılması ile silinen bir DataRow, geri alınamaz.

“Local
değişiklikleri veri kaynağı ile senkronize etmeyi planladığınız durumlarda
Delete metodunu kullanmanızı öneririm. Update metodu veri kaynağı ile
senkronizasyon işlemi sonrasında satır için AcceptChanges metodunu
çalıştıracaktır. Bir satırın Remove metodu ile silinmesi, Update
metodunun çalıştırılması bir concurrency violation hatası verecektir.”

DataView
Sınıfı

DataTable
nesnesindeki
DataView nesnesini, SQL Server’daki view nesneleri gibi görebiliriz.
DataView nesnesi, DataTable nesnesinde doğrudan mümkün olmayan
filtreleme, sorgulama ve gelişmiş arama özelliklerine sahiptir. Bir DataTable
nesnesi, farklı filtreleme ve sıralama ayarları tanımlanmış birden çok adet
DataView nesnesine sahip olabilir. Bir DataView nesnesindeki satırları RowFilter
veya RowStateFilter özelliklerinden biri ile filtreleyebilirsiniz. RowFilter
özellikleri WHERE ifadesi ile aynı formattadır. RowFilter ifadelerini
çift tırnak (“) içinde belirtiriz. Eğer ifade değişkenlerden değer alıyorsa
bunları tek tırnak ile birleştiririz. RowStateFilter özelliği DataTable
içindeki satırların DataViewRowState özelliklerine göre filtrelenmesini
sağlar. Bu özelliğe göre sıralama yaparak Delete metodu ile silinen,
yeni eklenen ve değerleri değiştirilen satırların listesini alabiliriz.

DataView style=font-size:10.0pt;font-family:Verdana> nesnesinin Sort metodu ile
DataView içindeki satırları sıralayabiliriz. Eğer birden çok satıra göre
sıralama yapmak istiyorsak sütun isimlerini virgül (,) ile ayırarak sıralamayı
gerçekleştirebiliriz. Bir sütuna göre artan (1-2-3-4..) sıralama yapmak için
ASC, azalan (9-8-7..) sıralama yapmak için DESC ifadelerini kullanırız.

RowFilter style=font-size:10.0pt;font-family:Verdana> özelliği ile bir satır veya sonuç
kümesi döndürebilsekte, bunun kullanımı çok verimli değildir. RowFilter
özelliğini genellikle bir defaya mahsus DataView nesnesini indexlemenin masrafından
kaçınmak için kullanırız. Eğer bir satır veya birden çok satır bulmaya ihtiyaç
duyarsanız Find veya FindRows metodunu çalıştırmanızı öneririm. 
Her iki metodunda çalışması için önce Sort özelliğini bulmak istediğiniz
kriterlere göre tanımlamanız gerekmektedir. FindRows metodu bir DataRowView
dizisi döndürecektir. Find metodu Find kriteri ile eşleşen satırın satır
indexini döndürecektir. Row indexi kullanarak DataView içindeki satırı
görüntüleyebilir veya ilgili DataTable’ı görüntüleyebiliriz.

Bir sonraki bölümde,
ADO.NET ile SQL Servera bağlantı oluşturma konusunu ele alıyor olacağız..

Kadir SÜMERKENT
kadirs@yazgelistir.com

ADO.NET

  1. Henüz yorum yok.
  1. Henüz geri izleme yok.