Makale Özeti

SQL Server 2005"in .NET Programcıları tarafından en önemli ve çekici özelliği olan Assembly host edebilme özelliğini inceleyeceğiz.

Makale

.NET ile SQL Server 2005 Programlama - 3

In-Proc Managed Provider Nesneleri

 

SQL Server 2000 ile ADO.NET kullanarak uygulama geliştirirken SqlClient Veri Sağlayıcısını (Data Provider)  kullanıyorduk. Bu durum hala geçerli fakat System.Data.SqlClient namespace hiyerarşisinde yer alan bu sağlayıcı SQL Server’a dışarıdan erişim için tasarlamıştır. Yani yazdığımız bir Windows uygulaması, ASP.NET uygulaması içerisinden SQL Server’a bağlanmak için kullanılr.

 

SQL Server üzerinden çalışacak olan .NET kodlarında kullanılması amacıyla System.Data.SqlServer namespace hiyerarşisinde yer alan yeni bir veri sağlayıcısı .NET 2.0 ile beraber SQL Server 2005 için gelmektedir. Bu veri sağlayıcısının adı “In-Proc Managed Provider” olarak geçer. In-Proc “In Process” kelimelerinden oluşturulmuş bir kısaltmadır.

 

Not : In-Proc Managed Provider sınıflarının kullanıldığı bir uygulamayı derlemek için sqlaccess.dll dosyasına referans verilmesi gereklidir.

 

%WINDIR%\Microsoft.NET\Framework\v2.0.40607\vbc.exe dosya.vb /r:System.Data.dll /r:"C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PublicAssemblies\sqlaccess.dll"  /t:library

 

Not: Bu bölümdeki örneklerde kodların derlenmesi ve sql server üzerine kaydedilmesi adımları anlatılmayacak sadece .net kodları verilecektir.

 

SqlContext Sınıfı

 

Aşağıdaki Sql Server Managed Provider (SqlClient) kullanılarak veri erişimi örnek kodunu inceleyiniz.

 

Dim baglanti As New System.Data.SqlClient.SqlConnection

baglanti.ConnectionString = "Server=(local)\YM;Database=Northwind;Trusted_Connection=True;"

Dim komut As New System.Data.SqlClient.SqlCommand

komut.Connection = baglanti

komut.CommandText = "SELECT ProductName FROM Products"

Dim okuyucu As System.Data.SqlClient.SqlDataReader

baglanti.Open()

okuyucu = komut.ExecuteReader

 

While okuyucu.Read

    ‘okuyucu(0) ile veriyi kullan

End While

 

okuyucu.Close()

baglanti.Close()

 

Yukarıdaki örnek Sql Server’a dışarıdan erişmek için kullanılacak olan kodu yapısını örneklemektedir. In-Proc Managed Provider’da hemen hemen her şey aynı buradaki yapı ile aynıdır. Ancak bazı önemli noktalarda farklar ortaya çıkmaktadır. In-Proc Provider ile yapılacak işlemler için bir SqlConnection bağlantı nesnesi oluşturmaya gerek yoktur.

 

Yazacağımız kodlar zaten Sql Server üzerinde çalışacaktır ve bağlantı nesnesi kendi içinde zaten açık durumdadır. Yazdığımız kod Sql Server üzerinde çalışırken bir bağlantı zaten vardır. Biz yazacağımız T-SQL kodlarını bu açık olan bağlantı üzerinden çalışırırız. In-Proc Managed Provider aktif durumdaki bağlantı nesnesine ve diğer nesnelere erişebilmemiz için yeni bir sınıf içermektedir : System.Data.SqlServer.SqlContext.

 

Sql Server üzerinde çalışacak olan ve Products tablosundaki tüm kayıtları dönecek olan yönetilen Stored Procedure şu şekile yazılmalıdır.

 

Dim komut As System.Data.SqlServer.SqlCommand = System.Data.SqlServer.SqlContext.GetCommand

komut.CommandText = "SELECT ProductName FROM Products"

 

Dim okuyucu As System.Data.SqlServer.SqlDataReader

 

okuyucu = komut.ExecuteReader

While okuyucu.Read

    ‘okuyucu(0) ile veriyi kullan

End While

okuyucu.Close()

 

Yukarıdaki kodu incelersek, Daha önceki dışarıdan erişim için yazdığım koddan farklı olarak burada kullanılan nesneler System.Data.SqlClient namespace’i içerisinde değil System.Data.SqlServer namespace’i içerisindedir. Çünkü yazdığımız bu kodların Sql Server üzerinde çalışmasını istiyoruz.

 

İkinci bir nokta ise kod yazarak, connectionstring belirleyerek bir bağlantı açılmamış olmasıdır. SqlContext sınıfını kullanarak aktif olan System.Data.SqlServer.SqlCommand nesnesi alınıyor. Bu nesne için bağlantı nesnesi belirlemeye gerek yoktur zaten aktif bağlantı içerisindeki nesne alınmıştır.

 

Bu örnekde sınıflar namespace hiyerarşileri yazılarak kullanılmıştır, System.Data.SqlServer namespace ekini her sınıfa eklemek yerine Imports System.Data.SqlServer yazdıktan sonra aynı kodu şu şekilde yazabilirsiniz.

 

Imports System.Data.SqlServer

...

...

...

Dim komut As SqlCommand = SqlContext.GetCommand

komut.CommandText = "SELECT ProductName FROM Products"

Dim okuyucu As SqlDataReader

okuyucu = komut.ExecuteReader

While okuyucu.Read

        okuyucu(0) ile veriyi kullan

End While

okuyucu.Close()

 

 

SqlPipe

 

Yukarıdaki örnekte veriler SqlDataReader nesnesi ile okunabilir durumdalar, while dögüsü ile her bir kayıt okunuyor. Fakat sorgu sonucu elde edilen verilerin istemciye aktarılmasını gerektiği durumlarda SqlPipe isminde yeni bir nesne kullanılır.

 

Az önceki örneğimizi verileri istemciye aktaracak şekilde düzenlersek.

 

Imports System.Data.SqlServer

...

...

...

Dim komut As SqlCommand = SqlContext.GetCommand

komut.CommandText = "SELECT ProductName FROM Products"

Dim okuyucu As SqlDataReader

okuyucu = komut.ExecuteReader

SqlContext.GetPipe.Send(okuyucu)

 

Yukarıdaki koddaki koyu bölüm SqlPipe türünde bir değişken tanımlayarak aşağıda şekilde de yazılabilir.

 

Dim myPipe As SqlPipe = SqlContext.GetPipe

myPipe.Send(okuyucu)

 

 

SqlPipe nesnesinin istemciye veri aktarımı sırasında en sık kullanılan metodları ve özellikleri şunlardır.

 

Execute : İki overload metodu vardır. Verilen SqlCommand veya SqlExecutionContext türünde parametreler alır, bunları çalıştırıp sonucu istemciye aktarır.

 

Send : Dört overload metodu vardır. İkisi istemciye veri döndürür. Bunlar ISqlReader ve ISqlRecord türünde parametrelerdir. Bir overload metodu istemciye hata mesajı, bir overload metodu ise mesaj döndürür.

 

SendResultsRow : İstemciye ISqlRecord türünde bir kayıt döndürür.

 

SendResultStart : Sonuçların istemciye gönderilmekte olduğunu bildirmek amacıyla SendingResults boolean özelliğini True yapar.

 

SendResultsEnd : Sonuçların istemciye gönderilmekte olduğunu bildirmek amacıyla SendingResults boolean özelliğini False yapar.

 

SendingResults :  Veri aktarımının devam edip etmediği ile ilgili bir veren boolean bir özelliktir.

 

 

SqlPipe ile İstemciye mesaj gönderilmesi

 

Dim myPipe As SqlPipe

myPipe = SqlContext.GetPipe

myPipe.Send("İstemciye giden mesaj")

 

SqlPipe ile SqlCommand nesnesinin istemciye aktarılması

 

Dim komut As SqlCommand = SqlContext.GetCommand

komut.CommandText = "SELECT ProductName FROM Products"

Dim myPipe As SqlPipe

myPipe = SqlContext.GetPipe

myPipe.Execute(komut)

 

Parametreli bir sorgunun istemciye aktarımı

 

Public Shared Sub Urunler(ByVal productID As SqlInt32)

  Dim komut As SqlCommand = SqlContext.GetCommand

  komut.CommandText = "SELECT ProductName FROM Products WHERE ProductID=@PID"

  komut.Parameters.Add("@PID", SqlDbType.Int).Value = productID

  Dim myPipe As SqlPipe

  myPipe = SqlContext.GetPipe

  myPipe.Execute(komut)

End Sub

 

SqlDefinition ve SqlExecutionContext

 

In-Proc veri sağlayıcısı bir sorgunun sabit öğeleri ve değişken öğeleri arasında yeni bir iş bölümü getirir. Bir sorgunun sabit öğeleri sorgu cümlesi, aldığı parametreler ve veri türleri gibi her çalışmasında aynı kalan, değişmeyen öğelerdir. Değişken öğeler ise parametrelerin değerleri ve aktif transaction ile ilgili bilgilerdir.

 

Sabit öğeler SqlDefinition, SqlExecutionContext sınıfları ile temsil edilirler.

 

SqlDefinition sınıfından bir nesne elde etmek için sınıf yapılandırıcısının iki overloadundan birisini kullanabiliriz. Bir tanesi SqlCommand nesnesi isteyen bir overloaddur. Diğeri ise bir SqlCommand için gerekli olan sql sorgusu, sorgunun türü,  ve ayrıntılı parametre bilgilerini istemektedir.

 

Üçüncü parametre olarak ayrıntılı parametre bilgisi için SqlMetaData türünde bir nesne dizisi istemektedir. SqlMetaData sınıfı SqlCommand için tanımlanacak olan parametreler ile ilgili veri türü, adı gibi bir çok bilgiyi yapılandırıcısında istemektedir. Bu sınıftan türemiş nesnelerinde değerleri readonly propertyler ile sunulur, yani ancak yapılandırma aşamasında verilen değerleri kullanırız, daha sonra bu özelliklerden birisinin değerini değiştiremeyiz.

 

SqlExecutionContext sınıfından bir nesne doğrudan “new“ ile türetilemez. Bir SqlExecutionContext elde etmek çin SqlConnection nesnesinin CreateExecutionContext metodu ile bir SqlExecutionContext elde edilebilir. CreateExecutionContext metodu parametre olarak bir SqlDefinition metodu bekler.

 

Örneğin :

 

Sub Urunler(ByVal productID As SqlInt32)

    Dim komut As New SqlCommand

    komut.CommandText = "SELECT ProductName FROM Products WHERE ProdcutID=@PID"

    komut.Parameters.Add("@PID", SqlDbType.Int)

    sqlcommand oluşturuldu

    Dim def1 As New SqlDefinition(komut)

    sqldefinition oluşturuldu

    Dim baglanti As SqlConnection

    baglanti = SqlContext.GetConnection

    Dim exc1 As SqlExecutionContext = baglanti.CreateExecutionContext(def1)

    exc1.SetSqlInt32(0, productID) 0.parametreye değer atandı

    executioncontext oluşturuldu

    SqlContext.GetPipe.Execute(exc1)

    exc istemciye gönderildi

End Sub

 




İlgili makaleler :
.NET ile SQL Server 2005 Programlama - 1
.NET ile SQL Server 2005 Programlama - 2
.NET ile SQL Server 2005 Programlama - 3



Cengiz HAN

cengizh@yazgelistir.com

www.cengizhan.com