Makale Özeti

ADO.NET ve veritabanlarına bağlanma kavramına biraz daha yakından göz atıyoruz.

Makale

ADO.NET Database Bağlantısı

 

 

Arkadaşlar kabul ediyorum ki ADO.NET ilk başta açıklaması bile zor olan bir teknoloji. Ama işin temelinde bilmeniz gereken tek bir şey var. ADO.NET Connected ve Disconnected  diye ayırabileceğimiz iki temel yapıdan oluşuyor.

 

Connected yapı aslında bizim ADO’dan alışık olduğumuz recordset diyebiliriz. İşlemler geliştirilmiş olmakla beraber eski recordset’imizin yapabildiği Select, Update, Delete vs. işlemleri başarıyla yapabiliyor. Sadece kullanılan methodlar biraz farklı. Mesela önceden çok kullandığımız MoveNext, MoveLast yada Recordset.EOF gibi methodlar artık kullanılmıyor. Buna rağmen eski ADO’da gerçekleştirdiğiniz bütün işlemleri farklı komut ve method’larla gerçeklekleştirebilirsiniz.

 

Disconnected yapının temelinde ise DataSet Nesnesi yatıyor ki dışarıdan bakınca kafa karıştıran olay işte bu. Ama gerçekten kafa karıştıracak bir durum yok. Dataset’ler veriyi client’ın cache’inde XML olarak tutuyor. Mesela siz laptopunuzla programınızdan database’inize bir kez bağlandıktan sonra fiyat listenizi çekiyor ve bağlantıyı kesip müşterinize gidiyorsunuz. Fiyat listenize aynen bağlantıdaymış gibi erişebilirsiniz. (Laptop’unuzu kapatmadığınız sürece tabiiki) Tek dezavantajı siz disconnect kaldığınız sürece diğer kullanıcılar tarafından yapılan değişiklikleri göremeyeceksiniz. Zaten bu bağlantı yapısı genellikle Web gibi live data gösterilmeyen, anlık değişiklerin gösterilmesi gerekmeyen ortamlar için tasarlanmış bir yapı.

 

Connected ve Disconnected yapının ortak kullandığı iki adet nesne var: Connection ve DataAdapter nesneleri.Connection Nesnesinin görevi database’le bağlantıyı kurmak, DataAdapter nesnesinin göreviyse database’e kayıt ekleme, silme, güncelleştirme gibi görevler için köprü vazifesi görmektir.

 

Yapıyı daha iyi kavrayabilmek için isterseniz aşağıdaki resime bir göz atalım.

 

 

 

Yukarıdaki resimde de gördüğünüz gibi ADO.NET ikiye bölünmüş durumda. Sol tarafta connected yapı, sağ tarafta disconnected yapı modelleniyor. Sağ tarafta gördüğünüz disconnected yapının temeli olan Dataset’in kullandığı yapılar ve XML ile olan alışverişi gösteriliyor.

Dikkat ettiyseniz DataSet’de veriye erişmek için connected yapının kullandığı Connection ve DataAdapter nesnelerini kullanıyor. Fakat daha öncede söylediğim gibi veri bir kez DataSet’e geldikten sonra XML formatında client cache’inde tutulmaya başlanıyor.

 

 

ADO.NET Connected Objects (Bağlantılı Nesneler)

 

 

Connection Object (Bağlantı Nesnesi)

 

 

Uygulamanız ve veri kaynağınız arasında veri taşımanın ilk gereksinimi bir bağlantı kurmaktır. ADO.NET biz programcılara veri kaynaklarını en iyi biçimde kullanabilmek için iki tip bağlantı şekli sunar.

           

  • SQLConnection SQL Server 7.0 ve sonrası için kullanılabilen özel olarak optimize edilmiş bağlantı kurar.

 

  • OleDbConnection Herhangi bir Database kaynağına OleDB vasıtasıyla bağlanmayı sağlar.

 

SQLConnection nesnesi SQL Server veritabanına bağlanırken OleDB katmanını atlayarak daha hızlı bir bağlantı gerçekleştirebilir.

 

 

Connection Strings (Bağlantı Dizeleri)

 

Her iki tip bağlantı da (SqlConnection yada OleDbConnection) database’e bağlanırken bir Connection String’e ihtiyaç duyar. Çünkü bunlar database’e uygulamamızı tanıtarak logon olmamızı, bağlantı esnasında hangi database’i ve ne tür güvenlik kullanacağımızı belirler.

 

Tipik bir ConnectionString aşağıda iki türde verilmiştir. İkisinin de görevi SQL Server’daki Northwind database’ine bağlanmaktır.

 

 

OleDbConnection Örneği

 

[Visual Basic]
Dim nwindConn As OleDbConnection = New OleDbConnection("Provider=SQLOLEDB;" & _
        "Data Source=localhost;" & _
        "Integrated Security=SSPI;Initial Catalog=northwind")
nwindConn.Open()
 
[C#]
OleDbConnection nwindConn = new OleDbConnection("Provider=SQLOLEDB;” + 
        Data Source=localhost;” +                                               
        "Integrated Security=SSPI;Initial Catalog=northwind");
nwindConn.Open();

 

 

SqlConnection Örneği

 
[Visual Basic]
Dim nwindConn As SqlConnection = New SqlConnection("Data “ & _
        “Source=localhost;Integrated Security=SSPI;" & _
        "Initial Catalog=northwind")
nwindConn.Open()
 
[C#]
SqlConnection nwindConn = new SqlConnection("Data Source=localhost; “ + 
        “Integrated Security=SSPI;Initial Catalog=northwind");

nwindConn.Open();

 

 

Yukarıdaki örneklerde SQL Server’a hem OleDbConnection String kullanarak hemde SqlConnection String kullanarak bağlanmayı gördük.

 

Fakat iki şey dikkatinizi çekmiş olmalı. Birincisi SqlConnection String’de provider belirtmedik. Çünkü sadece SQL Server için kullanılan bir bağlantıya ayrıca provider belirtmek gerekmiyor. İkincisi ise “Integrated security=SSPI” kelimesi. Bu kelime bağlantıyı kurarken windows Authentication kullanmasını sağlıyor.

 

Bunun bize faydası şu : Eskiden kullandığımız Connection String’lerde “user id=sa;password=pass;” gibi bir bölüm yazarak database’e login olacağımız kullanıcı adı ve password’unu belirtiyorduk. Fakat logon olmak için database’e gönderilen bu bilgi encrypyt edilmeden gidiyordu. Böylece kötü niyetli kişilerin login şifrelerimizi görme ihtimali doğuyordu.

 

Artık windows ile bütünleşik kullanılan login sistemi sayesinde windows’un kullandığı şifreleme sistemiyle daha güvenli olarak bağlantılarımızı gerçekleştirebileceğiz.

 

 

Bağlantıların açılıp kapanması

 

Database Connection’larda iki temel method bulunur. Bunlar: Open ve Close method’larıdır. Open method’u Connection String’deki bilgiyi kullanarak database ile bağlantıyı oluşturur. Close method’u ise database bağlantısını sonlandırır.

 

 [C#]
OleDbConnection nwindConn = new OleDbConnection("Provider=SQLOLEDB;Data Source=localhost;" +
                                                "Integrated Security=SSPI;Initial Catalog=northwind");
nwindConn.Open();
 

Command Object (Komut Nesnesi)

 

Eğer Database’e bağlantı kurduysanız artık komut gönderebilirsiniz demektir. DataAdapter kısmı burada devreye giriyor ve bağlantı tipiniz ne olursa olsun database’e yaptırmak istediğiniz işlem burada belirleniyor. Connection nesnesinde olduğu gibi database’e göndereceğiniz komut tipi ikiye ayrılmış durumda:

 

SqlCommand ve OleDbCommand

 

Eğer Sql Server kullanıyorsanız SqlCommand nesnesini, OleDb Provider kullanıyorsanız OleDbCommand nesnesini kullanmanız gerekiyor.

 

SqlCommand

[Visual Basic]
Dim catCMD As SqlCommand = New SqlCommand("SELECT CategoryID, “ & _
        “CategoryName FROM Categories", nwindConn)
 
[C#]
SqlCommand catCMD = new SqlCommand("SELECT CategoryID, CategoryName” + 
        “ FROM Categories", nwindConn);

OleDbCommand

[Visual Basic]
Dim catCMD As OleDbCommand = New OleDbCommand("SELECT CategoryID, “ & _
        “CategoryName FROM Categories", nwindConn)
 
[C#]
OleDbCommand catCMD = new OleDbCommand("SELECT CategoryID, “ & _
        “CategoryName FROM Categories", nwindConn);

 

 

 

 

 

Aslına bakarsanız bu bölüme bütün işlemlerin ayrıldığı ve performansın arttırıldığı bölüm diyebiliriz. Çünkü vereceğiniz komut tipine göre nesneler yaratılır ve her biri ayrı işlere yarar. Üç tip Command nesnesi vardır.

 

  • ExecuteNonQuery
  • ExecuteReader
  • ExecuteScalar

 

Şimdi bunları açıklayıp örneklendirelim

 

ExecuteNonQuery

 

Adından da anlaşılabileceği gibi Sorgu olmayan komutları çalıştırmak için kullanılır. Konuyu biraz daha açmamız gerekirse; Update, Delete, Create, Drop gibi database’den geriye değer yada veri döndürmeden işlem yapan Transact SQL Komutları için kullanılır. Eğer bu nesneyi “Select * from Employees” gibi bir Sql sorgusuyla kullanırsanız hiçbir sonuç alamazsınız.

 

[Visual Basic]
Dim cn As New OleDbConnection()
cn.ConnectionString = "Provider=SQLOLEDB;Data Source=(local)\NetSDK;" & _
                      "Initial Catalog=Northwind;Trusted_Connection=Yes;"
cn.Open()
Dim cmd As OleDbCommand = cn.CreateCommand()
cmd.CommandText = "UPDATE Customers SET CompanyName = NewCompanyName" & _
                  " WHERE CustomerID = ALFKI"
cmd.ExecuteNonQuery()

 

[C#]
OleDbConnection cn = new OleDbConnection();
cn.ConnectionString = "Provider=SQLOLEDB;Data Source=(local)\\NetSDK;" +
                      "Initial Catalog=Northwind;Trusted_Connection=Yes;";
cn.Open();
OleDbCommand cmd = cn.CreateCommand();
cmd.CommandText = "UPDATE Customers SET CompanyName = NewCompanyName " + 
                  "WHERE CustomerID = ALFKI";
cmd.ExecuteNonQuery();

 

ExecuteReader

 

Bu nesneyi de database’den gelen verileri okuyabilmek için DataReader nesnesiyle beraber kullanıyoruz. DataReader nesnesi bizlere forward-only ve read-only veri getirerek performans artışı sağlıyor. Genellikle verileri listelemek ve rapor almak için hızlı ve kullanışlı bir method olarak düşünülebilir.

 

Dim strConn, strSQL As String
strConn = "Provider=SQLOLEDB;Data Source=(local)\NetSDK;" & _
          "Initial Catalog=Northwind;Trusted_Connection=Yes;"
Dim cn As New OleDbConnection(strConn)
cn.Open()
strSQL = "SELECT CustomerID, CompanyName FROM Customers"
Dim cmd As New OleDbCommand(strSQL, cn)
Dim rdr As OleDbDataReader = cmd.ExecuteReader()
While rdr.Read()
    Console.WriteLine(rdr("CustomerID") & " – " & rdr("CompanyName"))
End While
rdr.Close()

 

[C#]
string strConn, strSQL;
strConn = "Provider=SQLOLEDB;Data Source=(local)\\NetSDK;" + 
          "Initial Catalog=Northwind;Trusted_Connection=Yes;";
OleDbConnection cn = new OleDbConnection(strConn);
cn.Open();
strSQL = "SELECT CustomerID, CompanyName FROM Customers";
OleDbCommand cmd = new OleDbCommand(strSQL, cn);
OleDbDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
    Console.WriteLine(rdr["CustomerID"] + " – " + rdr["CompanyName"]);
rdr.Close();

 

Yukarıdaki örnekte Command nesnemizin ExecuteReader Method’unu yarattığımız rdr objesine atadık. Daha sonra önemli bir değişiklik görmüş olmalısınız. 

 
While rdr.Read()
    Console.WriteLine(rdr("CustomerID") & " – " & rdr("CompanyName"))

End While

 

Yukarıdaki komutlarda rdr.EOF gibi bir işlem yapılmıyor. Hatırlarsanız ADO kullanırken recordsetteki bütün kayıtları görüntülemek için recordsetin EOF (End Of File) durumunu kontrol ederek sürekli döndürüyorduk. Artık bunun için yeni bir method’umuz var. Read method’unu loop içerisinde kontrol olarak kullanarak veriye erişebiliyoruz.

Önemli olan bir nokta da DataReader’la işimiz bittiğinde hemen kapatmamız gerektiği. Çünkü bu işlem Connected bir bağlantı şeklidir ve başka bir uygulama aynı kayıtlara ulaşmaya çalıştığında “Connection Busy” tarzında bir hata yada uyarı verebilir.

 
rdr.Close()

 

Bu yüzden DataReader nesnesinin kullanımı bittiğinde yukarıdaki örnekte olduğu gibi Close method’uyla kapatmalıyız.

 

ExecuteScalar

 

ExecuteScalar komutu da database’den tek bir değer döndürmek için kullanılır. Bildiğiniz gibi kayıt sayısı döndürmek için yada numeric alanlardan oluşan bir table kolonunun toplam değerini almak için kullandığımız Sql komutlar var. Mesela “Select Count(*) From Customers” komutu database’deki Customers tablomuzda kaç tane kayıdımız olduğunu geriye tek değer döndürerek bildirir.

Kullanımını bir örnekle görelim:

 

[Visual Basic]
Dim strConn As String = "Provider=SQLOLEDB;Data Source=(local)\NetSDK;" & _
                        "Initial Catalog=Northwind;Trusted_Connection=Yes;"
Dim cn As New OleDbConnection(strConn)
cn.Open()
Dim cmd As OleDbCommand = cn.CreateCommand()
 
cmd.CommandText = "SELECT COUNT(*) FROM Customers"
Dim intCustomers As Integer = CInt(cmd.ExecuteScalar())
 
cmd.CommandText = "SELECT CompanyName FROM Customers " & _
                  "WHERE CustomerID = ALFKI"
Dim strCompanyName As String = Convert.ToString(cmd.ExecuteScalar)

 

 

[C#]
string strConn = "Provider=SQLOLEDB;Data Source=(local)\\NetSDK;" +
                 "Initial Catalog=Northwind;Trusted_Connection=Yes;";
OleDbConnection cn = new OleDbConnection(strConn);
cn.Open();
OleDbCommand cmd = cn.CreateCommand();
cmd.CommandText = "SELECT COUNT(*) FROM Customers";
int intCustomers = Convert.ToInt32(cmd.ExecuteScalar());
 
cmd.CommandText = "SELECT CompanyName FROM Customers " +
                  "WHERE CustomerID = ALFKI";
string strCompanyName = Convert.ToString(cmd.ExecuteScalar());

 

Yukarıdaki örnekte iki adet farklı sorgu çalıştırılıyor. Bu sorgulardan "SELECT COUNT(*) FROM Customers" şeklinde olanı Customers tablosunun kayıt sayısını geri gönderirken "SELECT CompanyName FROM Customers WHERE CustomerID = ALFKI" tabloda bir select sorgusu çalıştırıyor ama tek bir kayıdın sadece bir alanını geriye döndürüyor. Bu durumda her iki sorgu da tek değer geriye döndürdüğü için ExecuteScalar yöntemini kullanmak çok daha sağlıklı. 
 

Buraya kadar öğrendiklerimiz Connected bağlantıydı. Bir sonraki konuda ADO.NET’in sunduğu en büyük yenilik olan Disconnected Nesne olan DataSet’e giriş yapacağız.

 

 

Mehmet ÇAKOĞLU

Solution Developer - S&T Turkey

 

Mehmet.cakoglu@protek.com.tr

mehmetcakoglu@msn.com

ICQ UIN# 44859105