Arşiv

Nisan 2010 arşivi

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

30 Nisan 2010

5- Verileri Düzenlemek,
Silmek ve Oluşturmak

Bu
bölümde veritabanı uygulamaları konusunda şu ana kadar değinmediğimiz
veritabanına yeni kayıt ekleme, mevcut kayıtları düzenleme ve silme işlemlerini
ele alıyor olacağız.

ADO.NET
ile Veritabanı İşlemleri
Verdana>
Bu bölümde SQL
Server’a veri eklemeyi, mevcut verileri düzenlemeyi ve silmeyi örnekleyen bir
uygulama geliştireceğiz. İşlemlerimizi yine Northwind örnek veritabanı üzerinde
gerçekleştiriyor olacağız. Örneğimizde yeni bazı işlemler göreceğimiz gibi şu
ana kadar gördüğümüz konuları da kullanacağız. Bunun için işe udpInsertANewShipper
adlı stored procedure’u oluşturarak başlayalım. Bu prosedür Shippers
tablosuna, aldığı CompanyName ve Phone parametrelerini ekleyen
bir INSERT INTO ifadesi içermektedir.

 

style=background:#E6E6E6;border-collapse:collapse;border:none id="table53">
padding:7.1pt 7.1pt 7.1pt 7.1pt>

font-family:"Courier New">–Northwind veritabanını kullanıyoruz

font-family:"Courier New">USE Northwind

font-family:"Courier New">GO

font-family:"Courier New"> 

font-family:"Courier New">–udpInsertANewShipper adında bir SP varsa

font-family:"Courier New">–yenisini oluşturmadan önce varolanı siliyoruz

font-family:"Courier New">IF EXISTS (SELECT ROUTINE_NAME

font-family:"Courier New">    FROM INFORMATION_SCHEMA.ROUTINES

font-family:"Courier New">    WHERE ROUTINE_TYPE = PROCEDURE AND

font-family:"Courier New">    ROUTINE_NAME = udpInsertANewShipper)

font-family:"Courier New">    DROP PROCEDURE udpInsertANewShipper

font-family:"Courier New">GO

font-family:"Courier New"> 

font-family:"Courier New">–udpInsertANewShipper adlı SPyi oluşturuyoruz

font-family:"Courier New">CREATE PROCEDURE udpInsertANewShipper

font-family:"Courier New">    @CompanyName nchar(40),

font-family:"Courier New">    @Phone nvarchar (24),

font-family:"Courier New">    @Identity int OUT

font-family:"Courier New">AS

font-family:"Courier New">INSERT INTO Shippers (CompanyName, Phone)

font-family:"Courier New">    VALUES(@CompanyName, @Phone)

font-family:"Courier New">SET @Identity = SCOPE_IDENTITY()

font-family:"Courier New">GO

 

Uygulamamızın
form tasarımı ise aşağıdaki gibidir:

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

style=font-size:10.0pt;font-family:Verdana>Şekil 5:1 – Tasarım Görünümü

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

Navigasyon
butonlarının hemen altında yer alan dört buton örneğimizin asıl konusu olan
veritabanı kayıt/güncelleme ve silme işlemlerinin gerçekleştirilmesini
sağlayacaktır. Bu butonlardan Temizle ve Ekle butonları birlikte
çalışmaktadır. Temizle butonu yeni girişin yapılabilmesi için metin kutularını
temizleyecektir.

 

Bu
örneğide kodlarla birlikte açıklayacağız.

 

style=background:#E6E6E6;border-collapse:collapse;border:none id="table54">
padding:7.1pt 7.1pt 7.1pt 7.1pt>

font-family:"Courier New">    DataAdapter ve
DataSet nesnelerine

font-family:"Courier New">    form içindeki
prosedürlerden

font-family:"Courier New">    erişmek istediğimiz
için

font-family:"Courier New">    modül seviyesinde
tanımlıyoruz.

font-family:"Courier New">    Dim dap1 style=color:blue>As SqlDataAdapter

font-family:"Courier New">    Dim das1 style=color:blue>As DataSet

font-family:"Courier New"> 

font-family:"Courier New">    Sub Populate()

font-family:"Courier New">        Northwind
veritabanı bağlantısı

font-family:"Courier New">        Dim cnn1 style=color:blue>As SqlClient.SqlConnection = _

font-family:"Courier New">        New
SqlConnection("Data Source=(local);" & _

font-family:"Courier New">            "Integrated Security=SSPI;"
& _

font-family:"Courier New">            "Initial Catalog=northwind")

font-family:"Courier New"> 

font-family:"Courier New">        Yeni bir
DataAdapter nesnesi oluşturuyor

font-family:"Courier New">        ve
SelectCommand belirtiyoruz

font-family:"Courier New">        dap1 = New
SqlDataAdapter _

font-family:"Courier New">            ("SELECT ShipperID, CompanyName,
Phone " & _

font-family:"Courier New">            "FROM Shippers", _

font-family:"Courier New">            cnn1)

font-family:"Courier New"> 

font-family:"Courier New">        Oluşturduğumuz
DataAdapter nesnesi için

font-family:"Courier New">        UpdateCommand
özelliğini belirtiyoruz

font-family:"Courier New">        dap1.UpdateCommand = _

font-family:"Courier New">            New
SqlCommand _

font-family:"Courier New">                ("UPDATE Shippers "
& _

font-family:"Courier New">                "SET CompanyName =
@CompanyName, " & _

font-family:"Courier New">                "Phone = @Phone " &
_

font-family:"Courier New">                "WHERE ShipperID =
@ShipperID", _

font-family:"Courier New">                cnn1)

font-family:"Courier New"> 

font-family:"Courier New">        UpdateCommand
özelliğinin kullanacağı iki

font-family:"Courier New">        parametreyi
oluşturuyoruz

font-family:"Courier New">        dap1.UpdateCommand.Parameters.Add _

font-family:"Courier New">            ("@CompanyName",
SqlDbType.NVarChar, 40, _

font-family:"Courier New">            "CompanyName")

font-family:"Courier New">        dap1.UpdateCommand.Parameters.Add _

font-family:"Courier New">            ("@Phone",
SqlDbType.NVarChar, 24, _

font-family:"Courier New">            "Phone")

font-family:"Courier New"> 

font-family:"Courier New">        Hangi satırın
güncelleneceğini ShipperID alanına

font-family:"Courier New">        göre
belirleyeceğiz. Shippers tablosundaki orijinal

font-family:"Courier New">        ShipperID
değerini kullanıyoruz

font-family:"Courier New">        Dim prm1 style=color:blue>As SqlParameter = _

font-family:"Courier New">            dap1.UpdateCommand.Parameters.Add _

font-family:"Courier New">            ("@ShipperID",
SqlDbType.Int)

font-family:"Courier New">        prm1.SourceColumn = "ShipperID"

font-family:"Courier New">        prm1.SourceVersion =
DataRowVersion.Original

font-family:"Courier New"> 

font-family:"Courier New">        DataAdapter
nesnesinin InsertCommand özelliğinde

font-family:"Courier New">        bir SQL ifadesi
değil, oluşturduğumuz Stored Procedureu

font-family:"Courier New">        kullanacağız.
Bu nedenle DataAdapter nesnesinin InsertCommand

font-family:"Courier New">        özelliğinin
CommandType değerinin CommandType.StoredProcedure

font-family:"Courier New">        olarak
değiştiriyor ve kullanacağımız SPnin adını belirtiyoruz

font-family:"Courier New">        dap1.InsertCommand = style=color:blue>New SqlCommand("udpInsertANewShipper",
cnn1)

font-family:"Courier New">        dap1.InsertCommand.CommandType =
CommandType.StoredProcedure

font-family:"Courier New"> 

font-family:"Courier New">        Kullanacağımız
SP için parametreleri belirtiyoruz

font-family:"Courier New">        dap1.InsertCommand.Parameters.Add _

font-family:"Courier New">            ("@CompanyName",
SqlDbType.NVarChar, 40, _

font-family:"Courier New">            "CompanyName")

font-family:"Courier New">        dap1.InsertCommand.Parameters.Add _

font-family:"Courier New">            ("@Phone",
SqlDbType.NVarChar, 24, _

font-family:"Courier New">            "Phone")

font-family:"Courier New"> 

font-family:"Courier New">        Hangi satırın
güncelleneceğini yine ShipperID

font-family:"Courier New">        alanına göre
belirliyoruz

font-family:"Courier New">        Dim prm2 style=color:blue>As SqlParameter = _

font-family:"Courier New">            dap1.InsertCommand.Parameters.Add _

font-family:"Courier New">             ("@Identity",
SqlDbType.Int, 0, "ShipperID")

font-family:"Courier New">        prm2.Direction = ParameterDirection.Output

font-family:"Courier New"> 

font-family:"Courier New">        DataAdapter
nesnemizin DeleteCommand özelliğine

font-family:"Courier New">        değer veriyoruz

font-family:"Courier New">        dap1.DeleteCommand = _

font-family:"Courier New">            New
SqlCommand("DELETE " & _

font-family:"Courier New">            "FROM Shippers " & _

font-family:"Courier New">            "WHERE ShipperID =
@ShipperID", cnn1)

font-family:"Courier New"> 

font-family:"Courier New">        Hangi satırın
silineceğini yine Shippers tablosundaki

font-family:"Courier New">        ShipperID
alanına göre belirleyeceğiz

font-family:"Courier New">        DeleteCommand
özelliği için kullanacağımız tek parametre

font-family:"Courier New">        olan
ShipperIDyi tanımlıyoruz

font-family:"Courier New">        Dim prm3 style=color:blue>As SqlParameter = _

font-family:"Courier New">            dap1.DeleteCommand.Parameters.Add _

font-family:"Courier New">            ("@ShipperID",
SqlDbType.Int)

font-family:"Courier New">        prm3.SourceColumn = "ShipperID"

font-family:"Courier New">        prm3.SourceVersion =
DataRowVersion.Original

font-family:"Courier New"> 

font-family:"Courier New">        Bağlantıyı
açıyoruz

font-family:"Courier New">        cnn1.Open()

font-family:"Courier New"> 

font-family:"Courier New">        DataAdapter
nesnesini kullanarak

font-family:"Courier New">        Oluşturduğumuz
DataSet içinde Shippers adlı

font-family:"Courier New">        DataTablea
verileri aktarıyoruz.

font-family:"Courier New">        das1 = New
DataSet

font-family:"Courier New">        dap1.Fill(das1, "Shippers")

font-family:"Courier New"> 

font-family:"Courier New">        DataSet nesnesi
ile çalışmak için

font-family:"Courier New">        açık bir
bağlantıya ihtiyacımız yok

font-family:"Courier New">        cnn1.Close()

font-family:"Courier New">    End style=color:blue>Sub

font-family:"Courier New";color:blue> 

font-family:"Courier New";color:blue> 

font-family:"Courier New">    ### FORM YÜKLENİYOR
###

font-family:"Courier New">    Private style=color:blue>Sub Form1_Load(ByVal
sender As System.Object, style=color:blue>ByVal e As
System.EventArgs) Handles style=color:blue>MyBase.Load

font-family:"Courier New">        Form
yüklenirken verileri DataSete aktarıyoruz

font-family:"Courier New">        Populate()

font-family:"Courier New"> 

font-family:"Courier New">        Form üzerindeki
metin kutularını ilgili

font-family:"Courier New">        alanlara
bağlıyoruz

font-family:"Courier New">        TextBox1.DataBindings.Add _

font-family:"Courier New">           (New
Binding("Text", das1, "Shippers.ShipperID"))

font-family:"Courier New">        TextBox2.DataBindings.Add _

font-family:"Courier New">           (New Binding("Text",
das1, "Shippers.CompanyName"))

font-family:"Courier New">        TextBox3.DataBindings.Add _

font-family:"Courier New">           (New
Binding("Text", das1, "Shippers.Phone"))

font-family:"Courier New"> 

font-family:"Courier New">        textbox1i
read-only hale getiriyoruz

font-family:"Courier New">        TextBox1.ReadOnly = style=color:blue>True

font-family:"Courier New">    End style=color:blue>Sub

font-family:"Courier New";color:blue> 

font-family:"Courier New">    ### NAVİGASYON BUTONLARI
###

font-family:"Courier New">    Private style=color:blue>Sub Button1_Click(ByVal
sender As System.Object, style=color:blue>ByVal e As
System.EventArgs) Handles Button1.Click

font-family:"Courier New">        İlk kayıda
gidiyoruz

font-family:"Courier New">        Me.BindingContext(das1,
"Shippers").Position _

font-family:"Courier New">            = Me.BindingContext(das1,
"Shippers").Position.MinValue

font-family:"Courier New">    End style=color:blue>Sub

font-family:"Courier New";color:blue> 

font-family:"Courier New">    Private style=color:blue>Sub Button2_Click(ByVal
sender As System.Object, style=color:blue>ByVal e As
System.EventArgs) Handles Button2.Click

font-family:"Courier New">        Bir önceki
kayıda gidiyoruz

font-family:"Courier New">        Me.BindingContext(das1,
"Shippers").Position -= 1

font-family:"Courier New">    End style=color:blue>Sub

font-family:"Courier New";color:blue> 

font-family:"Courier New">    Private style=color:blue>Sub Button3_Click(ByVal
sender As System.Object, style=color:blue>ByVal e As
System.EventArgs) Handles Button3.Click

font-family:"Courier New">        Bir sonraki
kayıda gidiyoruz

font-family:"Courier New">        Me.BindingContext(das1,
"Shippers").Position += 1

font-family:"Courier New">    End style=color:blue>Sub

font-family:"Courier New";color:blue> 

font-family:"Courier New">    Private style=color:blue>Sub Button4_Click(ByVal
sender As System.Object, style=color:blue>ByVal e As
System.EventArgs) Handles Button4.Click

font-family:"Courier New">        Son kayıda
gidiyoruz

font-family:"Courier New">        Me.BindingContext(das1,
"Shippers").Position _

font-family:"Courier New">            = Me.BindingContext(das1,
"Shippers").Position.MaxValue

font-family:"Courier New">    End style=color:blue>Sub

font-family:"Courier New";color:blue> 

font-family:"Courier New">    ### GÜNCELLE ###

font-family:"Courier New">    Private style=color:blue>Sub Button5_Click(ByVal
sender As System.Object, style=color:blue>ByVal e As
System.EventArgs) Handles Button5.Click

font-family:"Courier New">        DataTable
içinde farklı bir satıra giderek yapılan

font-family:"Courier New">        değişikliği
geçerli hale getiriyoruz

font-family:"Courier New">        If style=color:blue>Me.BindingContext(das1,
"Shippers").Position = 0 Then

font-family:"Courier New">            Me.BindingContext(das1,
"Shippers").Position -= 1

font-family:"Courier New">        Else

font-family:"Courier New">            Me.BindingContext(das1,
"Shippers").Position -= 1

font-family:"Courier New">            Me.BindingContext(das1,
"Shippers").Position += 1

font-family:"Courier New">        End style=color:blue>If

font-family:"Courier New";color:blue> 

font-family:"Courier New">        DataAdapter
nesnesinin Update metodunu kullanarak

font-family:"Courier New">        local verileri
veri kaynağı ile güncelliyoruz

font-family:"Courier New">        dap1.Update(das1, "Shippers")

font-family:"Courier New">    End style=color:blue>Sub

font-family:"Courier New";color:blue> 

font-family:"Courier New">    ### TEMİZLE VE YENİ
KAYIT EKLE ###

font-family:"Courier New";color:green> 

font-family:"Courier New">    Private style=color:blue>Sub Button6_Click(ByVal
sender As System.Object, style=color:blue>ByVal e As
System.EventArgs) Handles Button6.Click

font-family:"Courier New">        Eklenen satırı
daha sonradan güncelleyebilmek için

font-family:"Courier New">        İlk satıra
gidiyoruz

font-family:"Courier New">        Me.BindingContext(das1,
"Shippers").Position _

font-family:"Courier New">            = Me.BindingContext(das1,
"Shippers").Position.MinValue

font-family:"Courier New"> 

font-family:"Courier New">        Metin kutuları
için gerçekleştirdiğimiz

font-family:"Courier New">        veri
bağlantılarını kaldırıyoruz

font-family:"Courier New">        TextBox1.DataBindings.Clear()

font-family:"Courier New">        TextBox2.DataBindings.Clear()

font-family:"Courier New">        TextBox3.DataBindings.Clear()

font-family:"Courier New"> 

font-family:"Courier New">        Metin
kutularını temizliyoruz

font-family:"Courier New">        TextBox1.Text = ""

font-family:"Courier New">        TextBox2.Text = ""

font-family:"Courier New">        TextBox3.Text = ""

font-family:"Courier New">        Artık
uygulamamız yeni veri girişi için hazır durumda

font-family:"Courier New">    End style=color:blue>Sub

font-family:"Courier New";color:blue> 

font-family:"Courier New">    Private style=color:blue>Sub Button7_Click(ByVal
sender As System.Object, style=color:blue>ByVal e As
System.EventArgs) Handles Button7.Click

font-family:"Courier New">        Shippers
DataTableında yeni bir DataRow oluşturuyoruz

font-family:"Courier New">        ve değerlerini
form üzerindeki metin kutularından alıyoruz

font-family:"Courier New">        Dim newRow
As DataRow =
das1.Tables("Shippers").NewRow()

font-family:"Courier New">        newRow("CompanyName") =
TextBox2.Text

font-family:"Courier New">        newRow("Phone") = TextBox3.Text

font-family:"Courier New">       
das1.Tables("Shippers").Rows.Add(newRow)

font-family:"Courier New"> 

font-family:"Courier New">        Eklenen satırı
veri kaynağında geçerli hale getirmek için

font-family:"Courier New">        DataAdapter
nesnesinin Update metodunu kullanıyoruz

font-family:"Courier New">        dap1.Update(das1, "Shippers")

font-family:"Courier New"> 

font-family:"Courier New">        Metin
kutularından kaldırdığımız veri bağlantılarını

font-family:"Courier New">        yeniden
oluşturuyoruz

font-family:"Courier New">        TextBox1.DataBindings.Add _

font-family:"Courier New">           (New
Binding("Text", das1, "Shippers.ShipperID"))

font-family:"Courier New">        TextBox2.DataBindings.Add _

font-family:"Courier New">           (New
Binding("Text", das1, "Shippers.CompanyName"))

font-family:"Courier New">        TextBox3.DataBindings.Add _

font-family:"Courier New">           (New
Binding("Text", das1, "Shippers.Phone"))

font-family:"Courier New"> 

font-family:"Courier New">        Eklenen son
satırı görüntülemek için DataSet içindeki

font-family:"Courier New">        Shippers
DataTableının son satırına gidiyoruz

font-family:"Courier New">        Me.BindingContext(das1,
"Shippers").Position _

font-family:"Courier New">            = Me.BindingContext(das1,
"Shippers").Position.MaxValue

font-family:"Courier New">    End style=color:blue>Sub

font-family:"Courier New";color:blue> 

font-family:"Courier New">    ### SİL ###

font-family:"Courier New">    Private style=color:blue>Sub Button8_Click(ByVal
sender As System.Object, style=color:blue>ByVal e As
System.EventArgs) Handles Button8.Click

font-family:"Courier New">        DataSet
içindeki Shippers tablosuna

font-family:"Courier New">        dayanan bir
DataView oluşturuyoruz ve

font-family:"Courier New">        şu anda
bulunulan ShipperID ile eşleşen

font-family:"Courier New">        row indexini
buluyoruz

font-family:"Courier New">        Dim dav1 style=color:blue>As DataView = _

font-family:"Courier New">            New
DataView(das1.Tables("Shippers"))

font-family:"Courier New">        dav1.Sort = "ShipperID"

font-family:"Courier New">        Dim
rowIndex As Integer
= _

font-family:"Courier New">        dav1.Find(TextBox1.Text)

font-family:"Courier New"> 

font-family:"Courier New">        Bulunan satırı
silinmek üzere işaretliyoruz

font-family:"Courier New">       
das1.Tables("Shippers").Rows(rowIndex).Delete()

font-family:"Courier New"> 

font-family:"Courier New">        DataAdapter
nesnesinin Update metodunu kullanarak

font-family:"Courier New">        yaptığımız
işlemi SQL Server üzerinde ve DataSet

font-family:"Courier New">        üzerindeki
Shippers tablosunda geçerli hale getiriyoruz

font-family:"Courier New">        dap1.Update(das1, "Shippers")

    End Sub

 

Uygulamamız
çalışırken aşağıdaki gibi görünecektir..

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

style=font-size:10.0pt;font-family:Verdana>Şekil 5:2 – Uygulamamız Çalışıyor

 

Kaynaklar:…………….

style=font-size:10.0pt;font-family:Verdana>i.                   
MSDN style=font-size:10.0pt;font-family:Wingdings>J

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

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

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

 

Dokumanı
yukarıdaki kaynaklardan derlediğim bilgilerle oluşturdum. Farklı kaynaklarda
bulunan dokumanların derlemesi olarak görebiliriz, tabi bir artısı da Türkçe olması.

Faydalı
olacağını umuyorum.

ADO.NET

ADO .NET 2.0 İle Gelen Yenilikler -4

30 Nisan 2010

ADO .NET 2.0 İle
Gelen Yenilikler -4


Dataset &
DataTable Sınıflarına İlişkin Temel Değişiklikler





Dataset & Binary Serialization


Özellikle kurumsal ölçekte yazılan ve çok katmanlı mimarilerin
kullanıldığı uygulamalarda, katmanlar arasındaki veri iletişiminin son derece
efektif olması istenir. Veri iletişiminde efektiflik, hem iletişim
hızı hem de iletilen veri boyutunun makul sınırlar içinde olmasıdır.
Programcıların iletişim hızı ya da band genişliği gibi argümanlar üzerinde çok
da fazla inisiyatifleri olamayacağı gerçeği göz önüne alındığında, programcının
efektiflik adına fark yaratabileceği tek argüman; veri boyutunun
sınırlandırılmasıdır.

Konuya .NET perspektifinden bakılırsa, iletilmek istenen verinin
DataSet olması durumunda, programcının veri boyutları üzerinde de yapabileceği
fazla birşey kalmadığı görülecektir. Bu durum özellikle Remoting konusunda
daha da dramatik sonuçlara neden olmaktadır. Zira bir DataSetin içeriği,
binary serialization işlemine tabi tutulsa dahi kaçınılmaz olarak veri
yine XML formatında ifade edilmektedir. Sonuçta bu durum, verinin
boyutlarında (yaklaşık) üç katlık bir artışa neden
olmaktadır.   

DataSetin başından beri eleştirilen bu olumsuzluk, ADO.NET 2.0
da sınıfa eklenen RemotingFormat isimli bir property
sayesinde bertaraf edilmiştir. Böylece DataSet üzerinde gerçek anlamda
binary serialization yapabilmek mümkün hale gelmiştir.


Bu property SerializationFormat enumı türünde sabit değerleri
alabilmektedir. Bu enumın sayımladığı sabit değerleri şöyledir :



  • SerializationFormat.XML (default)


  • SerializationFormat.Binary


Örnek : Aşağıdaki
uygulamada veri tabanından alınan kayıtlarla doldurulan bir DataSet, binary
serialization işlemine tabi tutulmaktadır. RemotingFormat propertysine
SerializationFormat.Binary değeri atanarak uygulama çalıştırıldığında elde
edilen dosya büyüklüğü yaklaşık 139 KB iken, SerializationFormat.Xml değeri
atanarak çalıştırıldığında elde edilen dosya büyüklüğü yaklaşık 453
KB olduğu gözlenmiştir.  

Remoting performansı hakkında ise, (1000 kaydın üzerinde)
SerializationFormat.Binary değeri kullanıldığında, yaklaşık 80 katlık bir
artıştan söz edilebilir.    

static void Main(string[] args)


{


   
SqlConnection cnn =
new SqlConnection(“data source=localhost; initial catalog=Northwind; integrated
security=sspi”);


    SqlCommand cmd = new SqlCommand(“Select * From Orders”,
cnn);


    SqlDataAdapter adp = new SqlDataAdapter(cmd);


    DataSet ds = new DataSet();


    adp.Fill(ds);


    cnn.Close();


    // serialization işlemi


    BinaryFormatter format = new
BinaryFormatter();


    FileStream fs = new FileStream(“c:\sar.bin”,
FileMode.CreateNew); 

    

    ds.RemotingFormat =
SerializationFormat.Binary;


    format.Serialize(fs, ds);


}






Dataset – DataReader Entegrasyonu

Çalışma şekilleri açısından, birbirlerinden tümüyle farklı
iki paradigmanın temsilcisi durumunda olan bu sınıflar, (izole
tasarımları nedeniyle) içerdikleri verilerin kendi aralarındaki
transferine imkan sağlamamaktaydı. Oysa
söz konsusu
sınıflara ADO.NET 2.0 da yapılan eklentiler, birbirlerinden çok farklı iki
yaklaşımı öngören bu sınıfların entegrasyonunu mümkün kılmıştır.


Dataset ve DataTable sınıflarına eklenen Load() isimli üye fonksiyon;
parametresine aldığı IDataReader referansının temsil ettiği bellek bölgesindeki
kayıtların, Dataset ya da DataTable içerisine aktarımını sağlar.


public void Load(IDataReader reader, LoadOption
loadOption, DataTable[] tables);


Örnek :


SqlConnection cnn = new SqlConnection(“data
source=localhost; initial catalog=Northwind;


integrated security=sspi”);


SqlCommand cmd = new SqlCommand(“Select * From
Employees”, cnn);


SqlDataReader dr = cmd.ExecuteReader();


Dataset ds = new Dataset();


ds.Load(dr);


DataTableReader Sınıfı


Kütüphaneye yeni eklenen bu somut sınıf, bellekteki bir (veya daha
fazla) DataTable nesnesi içerisinde var olan kayıtları, üzerinde salt ve
ileri yönde okuma yapılabilen bir kayıt seti biçiminde elde etmeyi
sağlamaktadır. Tanımdan da anlaşılacağı gibi bu sınıfın çalışma
mekanizması ve içsel tasarımı, DataReaderı andırmaktadır. Zaten söz
konusu sınıf DbDataReader isimli taban sınıftan türetilmiştir.


Örnek :   


SqlConnection cnn = new SqlConnection(“data
source=localhost; initial catalog=Northwind;


integrated security=sspi”);


SqlCommand cmd = new SqlCommand(“Select
EmployeeID, LastName, FirstName From Employees”, cnn);


SqlDataAdapter adp = new SqlDataAdapter(cmd);


DataSet ds = new DataSet();


adp.Fill(ds);


cnn.Close();  


DataTableReader dtr = new
DataTableReader(ds.Tables[0]);


while (dtr.Read())


{


    listBox1.Items.Add(dtr[0].ToString() + ” ” +
dtr[1].ToString());


}


Not : Örnekte
DataTableReader nesnesinin yaratılışı için, sınıfın başlangıç
fonksiyonuna (constructorına) parametre olarak, üzerinden okuma yapılacak
DataTable nesnesinin referansının geçildiği görülmektedir. Bu işlem
DataTableReader ile DataTable ın ilişkilendirilmesini sağlamaktadır. Ancak
nesnenin yaratılışı için alternatif olarak, DataSet ya da
DataTable sınıflarına ait GetDataReader() isimli fonksiyon da
kullanılabilir. Zira bu fonksiyon, DataTableReader sınıfı türünde bir nesne
referansı döndürmektedir. Bu bağlamda aynı işlem aşağıdaki gibi de
yapılabilirdi :


DataTableReader dtr =
ds.Tables[0].GetDataReader();







Aykut TAŞDELEN




VB.NET  MVP (MS Most Valuable Professional)

ADO.NET

SQL Server ve Sayfalama

30 Nisan 2010

SQL Server ve Sayfalama


SQL Serverda pek çok
sayfalama yöntemi mevcuttur. Fakat bu işlem için kod yazmak gereklidir. Aklıma
gelen alternatifler;




  1. Sorguyu yapıp, tüm sonuç setini istemciye gönderip,
    istemci (client) tarafında, sayfalama yapmak;


  2. Sorguyu SQL Server tarafında yapıp, sonuç setini "temp" databaseine atıp,
    orada sayfalama yapmak

  3. SQL Server tarafında sorgulama yapıp, sadece ihtiyaç duyulan kayıtların
    gönderileceği şekilde sayfalama yapmak.


Bu yöntemlerin hepsinin kendine göre avantajları ve dezavantajları var. Yapılan
sorgulamadaki optimizasyon, Cacheleme ihtiyacı, problemlere göre değişik
yöntem seçilmesini gerektiriyor. Örneğin en çok kullanılan ve .Nette
programlaması kolay olan, birinci yöntem, (bana göre – veriyi
cachelemediğiniz sürece – ) Web tarafında pek kullanışlı değil ama Windows
uygulamaları için kullanışlı. Çok fazla kayıt olması durumunda, bir "Cache"
mekanizması implement edilmemişse, her requestte yeniden tüm sonuç setinin,
SQL serverdan Web Servera taşınmasına sebep olur. İkinci yöntemde temp
databaseine erişmeniz gerekir. Bu yazıda, ben 3. yöntemi biraz incelemek
istiyorum.


Öyle bir sorgulama yapmalıyım ki; bir kaç parametre vererek, milyonlarca kayıt
olan bir sorguda, sadece istediğim sayfadaki, kayıtlar geri dönsün ve SQL
serverdan Web servera taşınsın. Bütün bu işlemleri de ölçeklenebilir ve hızlı
bir şekilde yapsın. Bunun için, bir "stored procedure" yazdım. Her ne
kadar kaçınılması tavsiye edilse de, yarattığım stored procedure, içinde
dinamik bir SQL ifadesi oluşturup, çalıştırıyor.


SelectPage adını verdiğim stored procedureun kodunu aşağıda bulabilirsiniz.


Burada belirtmek isterim ki; belirli durumlarda, bu yazıda anlatılan uygulamadan
daha hızlı ve ölçeklenebilir çözümler olabilir.


Parametreler


Stored procedure çalışmak için 9 adet parametreye ihtiyaç duyuyor (sadece ilk üç
parametrenin doldurulması yeterlidir);




  • strFields: virgülle ayrılmış alan listesi,

  • strPK: Varsa tablonun "Primary Key"i (Bu değerin olması,
    sorgulamanın sonucunu dramatik bir şekilde artırır),

  • strTables: Tablo listesi (bu alana Joinler ve Hintler
    yazabilirsiniz.),

  • intPageNo: İstenen sayfa numarası (varsayılan : 1),

  • intPageSize: Sayfadaki kayıt sayısı (varsayılan : NULL –
    tüm kayıtları getirir) ,

  • blnGetRecordCount: Toplam kayıt sayısı da isteniyor mu?
    (varsayılan : 0 – hayır, eğer 1 ise ikinci bir RecordSette toplam kayıt sayısı
    döndürülür),

  • strFilter: Sorgunuzun WHERE kısmını buraya yazabilirsiniz
    (varsayılan : NULL – boş),

  • strSort: Sıralama değeri (ORDER BY) (varsayılan : NULL –
    boş),

  • strGroup: GROUP BY ifadesi (varsayılan : NULL – boş)

Örnekler, kullanım önerileri 


Northwind varitabanında çalışmaktadır. Aşağıdaki örnekleri, SQL Query Analyzeri
çalışıtırıp "Northwind" databaseini seçerek çalıştırabilirsiniz. Örneklerdeki
değerler, Northwindin ilk kurulumdaki verileri kullanılarak gösterilmiştir.
(SelectPage prosedürünü çağırabilmek için, önce "Northwind" veritabanında, bu
prosedürü yaratmalısınız.)




  • exec SelectPage
    *, EmployeeID, Employees

    Bu sorgu Emploeeys tablosundaki bütün kayıtları getirir. 

    "SELECT * FROM Employees" ifadesine eşittir.




  • exec SelectPage
    FirstName+ +LastName, EmployeeID, Employees, 2, 2, 1,
    TitleOfCourtesy<>Dr., LastName




    Bu sorgu; Employeelerin ad ve soyadını, Doktor Dr.
    olmayanları, Soyadına göre sıralayarak, 2. sayfadaki 2 kayıtı listeler,
    ayrı bir sonuç setinde de toplam kayıt sayısını döndürür.



    İlk kayıt setinde;


    Nancy Davolio

    Anne Dodsworth

    İkinci kayıt setinde ise,
    "8"
    değerini döndürür.



  • Üçüncü ve son örnekte, Northwind veritabanında, "Invoices" adlı bir View
    bulunmaktadır,

    SELECT Orders.ShipName, Orders.ShipAddress, Orders.ShipCity, Orders.ShipRegion, Orders.ShipPostalCode,
    	Orders.ShipCountry, Orders.CustomerID, Customers.CompanyName AS CustomerName, Customers.Address, Customers.City,
    	Customers.Region, Customers.PostalCode, Customers.Country,
    	(FirstName +   + LastName) AS Salesperson,
    	Orders.OrderID, Orders.OrderDate, Orders.RequiredDate, Orders.ShippedDate, Shippers.CompanyName As ShipperName,
    	"Order Details".ProductID, Products.ProductName, "Order Details".UnitPrice, "Order Details".Quantity,
    	"Order Details".Discount,
    	(CONVERT(money,("Order Details".UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice, Orders.Freight
    FROM 	Shippers INNER JOIN
    		(Products INNER JOIN
    			(
    				(Employees INNER JOIN
    					(Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID)
    				ON Employees.EmployeeID = Orders.EmployeeID)
    			INNER JOIN "Order Details" ON Orders.OrderID = "Order Details".OrderID)
    		ON Products.ProductID = "Order Details".ProductID)
    	ON Shippers.ShipperID = Orders.ShipVia
    




Bu sorguyu çalıştırdığınızda 2155 kayıt geri gönderiyor. Böyle bir sorguda 10
kayıttan oluşan 3. sayfayı göstermek istediğimizde;


exec Selectpage Orders.ShipName, Orders.ShipAddress, Orders.ShipCity, Orders.ShipRegion, Orders.ShipPostalCode,
	Orders.ShipCountry, Orders.CustomerID, Customers.CompanyName AS CustomerName, Customers.Address, Customers.City,
	Customers.Region, Customers.PostalCode, Customers.Country,
	(FirstName +   + LastName) AS Salesperson,
	Orders.OrderID, Orders.OrderDate, Orders.RequiredDate, Orders.ShippedDate, Shippers.CompanyName As ShipperName,
	"Order Details".ProductID, Products.ProductName, "Order Details".UnitPrice, "Order Details".Quantity,
	"Order Details".Discount,
	(CONVERT(money,("Order Details".UnitPrice*Quantity*(1-Discount)/100))*100) AS ExtendedPrice, Orders.Freight,
Orders.OrderID,
Shippers(nolock) INNER JOIN
		(Products(nolock) INNER JOIN
			(
				(Employees(nolock) INNER JOIN
					(Customers(nolock) INNER JOIN Orders(nolock) ON Customers.CustomerID = Orders.CustomerID)
				ON Employees.EmployeeID = Orders.EmployeeID)
			INNER JOIN "Order Details" ON Orders.OrderID = "Order Details".OrderID)
		ON Products.ProductID = "Order Details".ProductID)
	ON Shippers.ShipperID = Orders.ShipVia,
3, 10, 1


şeklinde bir sorgu yazmak yeterli olacaktır.





  • Gruplama özelliği için,




    exec SelectPage ProductName,
    Sum(ExtendedPrice) AS "Total", ProductName, Invoices, 2, 10, 0, null,
    null, ProductName



    şeklinde bir sorgu yazmak yeterli olacaktır.





  • Genelde ben bu prosedürü uygulamada direk kullanmıyorum, bu prosedürü çağıran
    prosedürler yazıyorum. Örneğin müşterileri sayfalamak istediğimde;
    "GetCustomersByPage" gibi bir prosedür yazıyorum;


    CREATE PROCEDURE GetCustomersByPage (@PageNo INT, @PageSize INT) AS
    	EXEC SelectPage *, CustomerID, Customers (nolock), @PageNo, @PageSize, 1
    RETURN



Stored Procedure


CREATE PROCEDURE SelectPage (
	@strFields VARCHAR(4000),
	@strPK VARCHAR(100),
	@strTables VARCHAR(4000),
	@intPageNo INT = 1,
	@intPageSize INT = NULL,
	@blnGetRecordCount BIT = 0,
	@strFilter VARCHAR(8000) = NULL,
	@strSort VARCHAR(8000) = NULL,
	@strGroup VARCHAR(8000) = NULL
)  AS 

	    DECLARE @blnBringAllRecords BIT
    DECLARE @strPageNo VARCHAR(50)
    DECLARE @strPageSize VARCHAR(50)
    DECLARE @strSkippedRows VARCHAR(50)

    DECLARE @strFilterCriteria VARCHAR(8000)
    DECLARE @strSimpleFilter VARCHAR(8000)
    DECLARE @strSortCriteria VARCHAR(8000)
    DECLARE @strGroupCriteria VARCHAR(8000)

    DECLARE @intRecordcount INT
    DECLARE @intPagecount INT   

    SET NOCOUNT ON  

    IF @intPageNo < 1 SET @intPageNo = 1
    SET @strPageNo = CONVERT(VARCHAR(50), @intPageNo)
    IF @intPageSize IS NULL OR     @intPageSize < 1
		SET @blnBringAllRecords = 1
    ELSE BEGIN
        SET @blnBringAllRecords = 0
        SET @strPageSize = CONVERT(VARCHAR(50), @intPageSize)
        SET @strPageNo =  CONVERT(VARCHAR(50), @intPageNo)
        SET @strSkippedRows = CONVERT(VARCHAR(50), @intPageSize * (@intPageNo – 1))
    END

    IF @strFilter IS NOT NULL AND      @strFilter !=   BEGIN
        SET @strFilterCriteria =  WHERE  + @strFilter +
        SET @strSimpleFilter =  AND  + @strFilter +
    END ELSE BEGIN
        SET @strSimpleFilter =
        SET @strFilterCriteria =
    END

    IF @strSort IS NOT NULL AND      @strSort !=
        SET @strSortCriteria =  ORDER BY  + @strSort +
    ELSE
        SET @strSortCriteria = 

    IF @strGroup IS NOT NULL AND      @strGroup !=
        SET @strGroupCriteria =  GROUP BY  + @strGroup +
    ELSE
        SET @strGroupCriteria = 

    IF @blnBringAllRecords = 1 BEGIN
        EXEC (SELECT  + @strFields +  FROM  + @strTables + @strFilterCriteria + @strGroupCriteria + @strSortCriteria)
    END ELSE BEGIN
        IF @intPageNo = 1
            EXEC (SELECT TOP  + @strPageSize +   + @strFields +  FROM  + @strTables + @strFilterCriteria + @strGroupCriteria + @strSortCriteria)
        ELSE BEGIN
            EXEC (SELECT  + @strFields +  FROM  + @strTables +  WHERE  + @strPK +  IN  +
                (SELECT TOP  + @strPageSize +   + @strPK +  FROM  + @strTables +
                     WHERE  + @strPK +  NOT IN  +
                        (SELECT TOP  + @strSkippedRows +   + @strPK +  FROM  + @strTables + @strFilterCriteria + @strGroupCriteria + @strSortCriteria + )  +
                    @strSimpleFilter +
                    @strGroupCriteria +
                    @strSortCriteria + )  +
                @strGroupCriteria +
                @strSortCriteria
            )
        END
    END
    IF @blnGetRecordCount = 1
        IF @strGroupCriteria !=
	        EXEC (SELECT COUNT(*) AS RECORDCOUNT FROM (SELECT COUNT(*) FROM  + @strTables + @strFilterCriteria + @strGroupCriteria + ) AS tbl (id))
        ELSE
            EXEC (SELECT COUNT(*) AS RECORDCOUNT FROM  + @strTables + @strFilterCriteria + @strGroupCriteria)



Mert Sakarya

Uygulama Mimarı

mertsakarya@hotmail.com


Doğan Online A.Ş.

ADO.NET

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

ADO.Net ile Excel tablolarına DB gibi baglanmak

30 Nisan 2010

Excel dosyalarına aynen bir DB gibi erişmek, ADO.Net ile kolayca mümkün oluyor. Pek bir alternatif olarak sayılmasada, çogu zaman ihtiyaç duyula
bilmektedir. ADO.Net ile bu işlemi gerçekleştirmek, 2 aşamada mümkün oluyor.


1. Her hangi bir Excel dosyasındaki belirledigimiz bir hücre grubunu ilk olarak tanımlamamız gerekiyor. ADO.Net bu tanımladıgımız alanlari sanki bir veri tablosu gibi
algılayacak. Benim örnek oluşturdugum tablo aşagıdaki gibidir



Tablomuzu oluşturduktan sonra, "Insert -> Names -> Define" ile üzerinde çalışacagımız tabloyu ve verilerini oluşturacagız.

 

"Define" kısmında gelen pencerede, ben "isimler" diye bir define tanımladim (yani tablomun adı "isimler"), "Add" tuşunana basmadan önce aşagıdaki "Refers to:" kısmına hangi hücreleri kapsadıgını seçmemiz gerekmektedir.



        Tıpkı aşagıdaki gibi, ilgili alanı seçiyoruz.
 

                       

A1 den B7 e kadarlık hücre blogunun hepsini "isimler" olarak tanımladık. Artık kaydedip cıkabiliriz.

2. Bu kısımda ise C# da erişim yolunu görecegiz;

İlk olarak
using
System.Data.OleDb;
uzay ismini eklemeyi unutmuyoruz.
Ben aşagıdaki gibi oldukca basit bir form hazırladım, bir listview ve bir
buttondan oluşuyor.


private

void btn_XLSden_Click(object
sender, System.EventArgs e)
{
       //connection stringimiz
       //bin klasorumuzn icindeki derledigimiz
EXE ile aynı klasorun iceresinde
       string connstr =
"Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=Deneme.XLS;Extended Properties="Excel 8.0;HDR=Yes;IMEX=2""
;

       // EXCEL dosyamızı açıyoruz ve okuyoruz
       OleDbConnection conn = new
OleDbConnection(connstr);
       conn.Open();
             //isimler
tablosu aslında Excel dosyamızda define ile tanimladigimiz alanin ismi
             OleDbCommand cmd = new
OleDbCommand("Select * From isimler",conn);
             OleDbDataReader dtr = cmd.ExecuteReader();

    
        //eger tablo bos degil ise
             //kolon isimlerini alıp
listview in kolonlarını olusturuyoruz
             for(int
i=0;i<=dtr.FieldCount-1;++i)
            
listview1.Columns.Add(dtr.GetName(i),65*(i+1),HorizontalAlignment.Center); 


             //tek tek okuyoruz ve listviewe ekliyoruz
             ListViewItem satir = new
ListViewItem();
             while(dtr.Read())
                    {
                           satir = listview1.Items.Add(dtr[0].ToString());
                           satir.SubItems.Add(dtr[1].ToString());
                    }
             //sonlandırıyoruz
              dtr.Close();
       conn.Close();
}

Fazladan bir açıklama yapmaya gerek duymuyorum, gerekli
açıklamaları comment olararak kodlarla birlikte yaptım. Gördügünüz gibi oldukca
basit, diger işlemleride sıradan ADO.Net commandları ile
gerçekleştirebilirsiniz.

ConnectionString dogru yapıldıgı anda hiç bir sorunla
karşılaşmazsınız.


"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Deneme.XLS;Extended
Properties="Excel 8.0;HDR=Yes;IMEX=2""

Buradaki "Deneme.XLS"in yeri farklı bir klasorde ise
c:\denemeler\deneme.XLS gibi
yerini gösterebilirsiniz. Hepinize çalışmalarınızda başarılar diliyorum, kolay
gelsin…

Giriş

.Net Framework, veritabanı ile çalışmak için yazılım geliştiricelere ADO.NET’i sundu. ADO.NET bize veriyi görüntülemek ve veri üzerinde işlemler yapmamızı sağlar. Veritabnındaki bazı bilgilere erişmek ve uygulama üzerinde bazı parametreleri kullanabileceğini göz önünde bulunduralım. Bu işlemi 6-7 satır kod yazarak kolayca yapabiliriz. Fakat, 5-6 satır kodu tekrar tekrar yazmak zorunda kaldığımızda bu işlemi yapmak kolay olmayacaktır.

Microsoft bunun için, Daha az kod ile ortak işleri yapmak için kullanılabilen Data Access Application Block’u geliştirdi. Data Access Application Block’u aşağıdaki adresten indirebilirsiniz. 

 
 
http://msdn2.microsoft.com/en-us/library/ms954827.aspx


Microsoft .net Data Access Application Block Nasıl Kullanılır ?

İlk olarak
Data Access Application Block Version 2.0.(Daha eski/yeni versionda olabilir) indirip kuralım. Ilk olarak the Microsoft .net Data Access Application Block projesi için .dll dosyası oluşturacağız. Projeyi build ettikten sonra kendi projemize basitçe ekleyebiliriz. Kendi projemize ekledikten sonra bin klasörü içindeki .dll dosyasınıda build edelim.

Data Access Application Block olmadan Dataya Erişmek

İlk olarak Application olmadan veriye nasıl erişildiğine bakacağız. Aşağıda veritabanına 2 parametre ekleyen basit bir örnek yapacağız.

string connectionString = (string)
ConfigurationSettings.AppSettings["ConnectionString"];
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand(“INSERT_MUSTERI”,connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter(“@Name”,SqlDbType.NVarChar,50));
command.Parameters["@Name"].Value = txtName.Text;
command.Parameters.Add(new SqlParameter(“@Surname”,SqlDbType.NVarChar,10));
command.Parameters["@Surname "].Value = txt Surname.Text;
connection.Open();
command.ExecuteNonQuery();
connection.Close();

Görüldüğü gibi veritabanına parametre eklemeye çalıştığımızda 6-7 satır kod ile işimizi tamamladık. Fakat 10 yada daha fazla parametre eklemeye çalıştığımızda geliştirme zamanı bir hayli uzayacaktı.

Şimdi aynı işlemi
Microsoft .net Data Access Application Block kullanarak yapalım.

using Microsoft.ApplicationBlocks.Data;
SqlHelper.ExecuteNonQuery(connection,”INSERT_MUSTERI”,new
SqlParameter(“@Name”,txtName.Text) ,new SqlParameter(“@Surname”,txt Surname.Text) );

Gördüğünüz gibi 5-6 satır kod yazmak yerine işimizi tek satırda tamamladık.

Bu işlemi SqlHelper classı ile yaptığımız gördük. Peki bu SqlHelper nereden çıktı?

Projemizin namespacelerine
Microsoft.ApplicationBlocks.Data

eklersek SqlHelper Classına erişebiliriz. SqlHelper Classı veritabanına erişmek için static metodlar içeren ve Microsoft tarafından geliştirilen bir classdır. Her hangi bir text editörü ile SqlHelper Classını açabilir ve inceleyebilirsiniz.

SqlHelper Class

SqlHelper’in içindeki static metodlar;

ExecuteNonQuery

ExecuteDataSet

ExecuteReader

ExecuteScalar

ExecuteXMLReader

Evet artık örneğimize geçebiliriz. İlk olarak bir Windows Application açalım.

Şimdi SqlHelper Classını projemize ekleyelim. (DLL olarak da ekleyebiliriz).


  
 

Şimdi projemizin namespacelerine ApplicationBlocks.Datayı ekleyelim.

using Microsoft.ApplicationBlocks.Data;

Ekledikten sonra formumuzun üzerine 1 adet buton ve bir gridview ekleyelim.


 

Evet Şimdi ExecuteDataseti çalıştıracak kodları yazalım.

                                                    string sqlstring = “Select * from Musteriler”;

                                                    dataGridView1.DataSource = SqlHelpera.ExecuteDataset(“Data Source=localhost; Initial Catalog=SemGoksuDB; trusted_connection=yes”, CommandType.Text, sqlstring).Tables[0];

                 

 
 

Şimdi projeemizi çalıştıralım.

 
 


 

Projemizi çalıştırdıktan sonra kayıtlarımızı listeledik. Gördüğünüz gibi çok kolay bir şekilde 1-2 satır ile işimizi yaptık.

Bu makalenin de sonuna geldik, başka bir makalede görüşmek üzere başarı ve iyi günler dilerim.

Sem GÖKSU
MCP | MCAD.NET | MCTS

Örnek Kodlar için mail adresimi kullanabilirsiniz

semgoksu@semgoksu.com

Kaynaklar



http://msdn.microsoft.com

SqlBulkCopy Sınıfını Kullanarak Veri Transferi

Çalıştığım merkezdeki 6 yıllık milyonlarca verinin bir yerden başka bir yere aktarılması gerekiyordu. Bu sefer alışmış olduğum klasik yöntemler yerine başka bir çözüm aradım. Sonunda.NET 2.0 ile gelen SqlBulkCopy sınıfı ile karşılaştım. İşte bu makalede bu sınıf ile neler yapabileceğimize bir göz atacağız.

Bir kaynaktan başka bir kaynağa veri transferi, yazılım dünyası içinde sıklıkla karşılaşılan bir durumdur. Bu işlem birçok farklı senaryo için uygulanabilir. Eski sistemden yeni sisteme geçiş, veri yedekleme, farklı yerlerden veri toplama vs. .NET 2.0, farklı kaynaklardan SQL Server veritabanına veri aktarmanıza olanak veren SqlBulkCopy sınıfını içerir (System.Data.SqlClient.SqlBulkCopy). İşte bu makalede, SqlBulkCopy sınıfını farklı yönleriyle ele alacağız.

Veritabanı Tasarımı

Şimdi, herkesin de rahatlıkla uygulayabilmesi için elimizdeki kaynakları da kullanarak bir veritabanı tasarımı yapalım. SQL Server 2005 kurulu tüm bilgisayarlarda bulunan AdventureWorks veritabanındaki Person.Address tablosunu baz alarak 3 yeni tablo yapalım. Aşağıdaki veritabanı diyagramını inceleyerek; tabloları oluşturabilirsiniz. Çok sade, hoş bir tasarım oldu :)




Burada Address_Old ve Address_New tablolarımız aynı eski Address tablosunda olduğu gibi aynı şemaya sahip. Sadece Address_Specific tablosu bunlardan farklılık gösteriyor. Bunun sebebini makalenin ilerleyen bölümlerinde bulabileceksiniz.

Aslında etkili gösterim için daha fazla kayıt içeren bir tablo bulmak isterdim ama Address_Old tablosu da yeterli olacak sanırım. Bu tablo tam 19614 satır içeriyor. Şimdi burada asıl düşünülmesi gereken kayıtların çokluğu değil; ani ya da acil bir durum karşısında bu kadar kaydı nasıl bir yerden başka bir yere aktaracağımızdır. Örneğin, tüm bu tablo satırlarını Address_Old tablosundan Address_New tablosuna nasıl aktaracağız. Şimdi bu gibi senaryolara bir bakalım.

Address_Old Tablosundan Address_New Tablosuna Veri Transferi

SqlBulkCopy, WriteToServer adında veriyi bir kaynaktan hedefteki kaynağa transfer etmek için kullanılan bir instance metot içerir. WriteToServer metodu, DataRow[] dizisinde, DataTable da ve DataReader üzerinde işlem yapabilir. Duruma göre istediğiniz herhangi bir taşıyıcıyı seçebilirsiniz. Bunda bir kısıtlama yok ama birçok durumda olduğu gibi DataReader ı seçmek iyi olur sanırım. Bunun nedeni DataReader yapısından kaynaklanır. DataReader sadece ileri (forward-only) ve salt okunabilir (read-only) çalışır. Herhangi bir şekilde veri tutmasına, bağlamasına gerek yoktur ve işte bu yüzden DataTable ve DataRows[] dan kat kat hızlı çalışır (bu senaryoda). Aşağıdaki kodda kaynak tablomuzdan hedefteki tablomuza veriyi nasıl aktarabileceğimizi görebilirsiniz.




Şimdi burada bahsedilecek birkaç nokta var. Öncelikle, veritabanı tablosundan satırları çekmek için DataReader kullanıyoruz. SqlBulkCopy sınıfı nesnesi bulkCopy, DestinationTableName özelliğine burada Address_New olan tablomuzu set ediyor. Address_New burada hedef tablomuz. Çünkü verileri Address_Old tablosundan, Address_New tablosuna aktaracağız. bulkCopy nesnesi, NotifyAfter özelliği tarafından belirlenen satırlara ulaştıktan sonra SqlRowsCopied olayını da çalıştırıyor. Bunun anlamı da, bu olay NotifyAfter özelliği 1000 olarak ayarlandığından dolayı; her 1000 satırdan sonra SqlRowsCopied olayı çalıştırılacaktır.

Burada BatchSize özelliği de, performans büyük çoğunlukla ona bağlı olduğu için oldukça önemlidir. BatchSize, veri transferini başlatmak için bir defada veritabanına ne kadar satırın gönderilmesi gerektiğini tutar. Burada bu değeri biz 500 olarak ayarladık. Bunun anlamı bir defada, DataReader, bulk copy işlemini gerçekleştirebilmek için veritabanına gönderilmek üzere 500 satır okuyacaktır. Varsayılan olarak BatchSize 1 olarak ayarlanmıştır. Bu da, veritabanına her bir satırın tek tek gönderileceği anlamını taşır.

Farklı BatchSize değerleri size farklı sonuçlar verecektir. Burada hangi BatchSize değerinin size en çok uyacağını farklı testler yaparak bulabilirsiniz.

Farklı Şemalara Sahip Tablolar Arasında Veri Transferi


Bir önceki örnekte, her iki tablomuzda aynı şemaya sahipti. Fakat bazen, farklı şemalara sahip tablolar arasında da veri transferi yapmak zorunda kalabiliyoruz. Şimdi bir adres tablosu içindeki tüm adres satırlarını ve posta kodlarını, Address_Old tablosu içinden Address_Specific tablosu içine aktarmak istediğimizi varsayalım. Farklı sütun isimlerini sahip oldukları için, dolayısıyla bu iki tablonun şemaları da farklıdır. En başta gördüğümüz veritabanı tasarımını gösteren diyagram resminde de bunu görebiliriz.




Burada ColumnMappings koleksiyonu, kaynak tablo ile hedef tablo arasındaki sütunları belirlemede kullanılır.

XML Dosyasından Veritabanı Tablosuna Veri Transferi

Veri kaynaklarını sadece veritabanı tabloları ile sınırlayabilir miyiz? Elbette hayır. XML dosyalarını da veri kaynağı olarak kullanabiliriz. Aşağıda, bulk copy işleminde kaynak olarak kullanabileceğimiz; çok basit bir XML dosyası var.


Addresses.XML Dosyası


Bu da kaynak kodumuz.




Dosya ilk olarak DataTable içinde okunuyor ve daha sonra SqlBulkCopy sınıfının WriteToServer metoduna aktarılıyor. Yine, hedef tablo olarak, Address_Specific tablosunu seçtiğimiz için ColumnMappings kullanarak sütünları belirliyoruz.

Daha bunun gibi birçok senaryo yaratarak sizde değişik örnekler yapabilirsiniz. Bu arada SqlBulkCopy sınıfının gücünü özellikle belirtmek isterim. Örneğimizde kullandığımız 19614 satırlık kaydın bir tablodan diğerine aktarılması, bir göz kırpması için geçen süre ne kadarsa o kadar sürdü :)

Özet


Bu makalede, .NET 2.0 ile birlikte gelen SqlBulkCopy sınıfını nasıl kullanabileceğimizi gördük. SqlBulkCopy sınıfı, bir veri kaynağından SQL Server veritabanına veri transfer etmek istediğimizde; işimizi oldukça kolaylaştırır. Sizde değişik senaryolarla bunu test edebilirsiniz.

Not: Bu sınıf, .NET Framework .NET Compact Framework 3.0 ve 2.0 versiyonlarının tümünde desteklenmektedir.

Bir sonraki makalelerde görüşmek üzere. İyi çalışmalar…

Tayfun AKCAY

tayfun@tayfunakcay.com


ADO.NET ile MySQL Kullanım Örneği – 1
Merhaba arkadaşlar;
Öncelikle bu makalemizin istek üzerine yayınlandığını belirterek sözlerime başlamak isterim. Bu da demektir ki Mspro.org adresinden bana istekte bulunabilirsiniz. Bu makalemizin konusu ADO.NET ile MySQL veritabanı ilişkileri ile ilgili olacak.  INSERT, DELETE, UPDATE gibi SQL komutlarını inceleyeceğiz.  Şimdi ilk yapmamız gereken VS.NET 2005 ya da Visual Web Developer içinde MySQL kullanabilmemiz için Bir adet programcığımız var. Bunu belirteceğim adresten indirip yüklemeniz gerekmektedir. Daha sonrada nedir bu yüklediğimiz şey onu açıklayacağım. İşte o adres http://dev.mysql.com/get/Downloads/Connector-Net/mysql-connector-net-5.0.8.1.exe/from/http://mysql.easynet.be/ . Dosyayı bilgisayarınıza indirip kurma işlemini gerçekleştirdikten sonra vs.net i açıp yeni bir AJAXEnabledWebSite oluşturun.  Ajax Projesi oluşturmamızın sebebi örneğimiz içerisinde Update Panel kullanacak olmamız. Yani kısaca Update Panel nasıl kullanılır onu da göreceğiz. Makalemizde MySQL’ in pc nizde kurulu olduğunu ve kullanmayı bildiğinizi varsayarak devam edeceğiz.
Projeniz oluştuktan sonra açıklamalarıma başlayabiliriz. Bu yüklemiz olduğumuz MySQL .NET connector adındaki setup dosyası bize .net içerisinde MySQL kullanmamıza yardımcı olacak referans dosyalarını getirmekte ve  vs.net e entegre etmektedir. İlk olarak oluşturduğumuz projemize bu dosyaları referans etmemiz gerekmektedir. Aşağıdaki resimler de bunu nasıl yapacağınız sırayla gösterdim.

 

Projeniz artık MySQL ile çalışabilecek her şeye sahip. Şimdi deneme adında bir Database oluşturun ve bu Database içerisie maillist adında bir tablo ve bu tablonun içerisine aşağıda ki resimde görünen alanları ekleyiniz.

Id alanı auto inc. Olacak buna dikkat ediniz.

Evet zannediyorum  db olayını hallettiniz. Zaten burada db yaratma gibi konulara girmeyeceğiz. Neyse
Db hazır olduğuna göre şimdide sıra form tasarımımızda. Aşağıdaki tabloda formumuza hangi kontrollerin olması gerektiği ve bu kontrollerin hangi isimlere sahip olması gerektiği verilmiştir.  İsterseniz farklı isimler verebilirsiniz. Fakat örneği bitirdikten sonra bunu denemeniz daha sağlıklı olacaktır.

Yapmamız gereken son şey ise GridView kontrolünü update panel içerisine almak. Sonra form görüntümüz aşağıdaki gibi olacaktır.

                Formumuzu bu şekilde düzenledikten sonra şimdi sıra kodlarımızı yazmaya geldi. Aşağıda vermiş olduğum ekran görüntüsünde bulunan kodlar tam olarak şu işlemi yapmaktadır.  MySQL veritabanına bağlanmamız için gerekli olan namespace (isim uzayları) lerdir. Gerekli nesneleri .NET içerisine import eder ve kullanmamıza olanak verir. Eğer eklemezsek ne olur ?. MySQL ile hiçbir şekilde ilişki kuramayız. Farklı metotlar dışında tabii ki.

Not: Bu Kısım sayfamızın en başına import edilecek. Bildiğinizi biliyorum fakat hatırlatayım dedim.
Burayı da hallettiğimize göre şimdi sıra asıl kodlarımızda işte o kodlarda aşağıda. İsterseniz senaryomuzdan bahsedeyim biraz. Ne yapacağız. Basit bir işlem hemen korkmayın. Gördüğünüz gibi 2 adet textbox ımız var. Bu kontrollerin içeriğini dbye yazdırıp buradan da gridview kontrolünde göstereceğiz. Bu şekilde basit bir mail list iniz olacak. Artık kodları yazmaya başlıyoruz.

 

Yukarıda göründüğü gibi artık gridview kontrolümüz dolu bir şekilde geliyor. Şimdi yapmamız gereken şey db mize veri eklemek işte bunun içinde aşağıdaki kodları yazdım.

Bu void i ise btn_ok in click eventinde çağırıyoruz. Bu durumda şöyle bir şey çıkıyor ortaya. Update panel nasıl çalışacak. Tabii ki Asenkron çalışacak. Yoksa sayfa gider ve gelir. Aşağıda resimlerini verdim. Aralarda da açıklamalar yaptım. Konumuz Update panel olmadığı için fazla detaya girmiyoruz. Zaten nette gerekli dokümanları fazlasıyla bulursunuz. Bu nedenled e Update panel ile ilgili bir yazı düşünmüyorum.

Update Panel seçili iken Properties penceresinden Triggers Özelliğine tıklıyoruz. Sonra.

Add butonundan AsyncPostBack Trigger seçeneğini seçiyoruz. Members bölümüne bir Asenkron üyenin eklendiğini göreceğiz. Properties kısmında aşağıdaki değişiklileri yapıp OK butonuna tıklıyoruz. Asenkron seçmemizin sebebi sayfamızın yeniden yüklenmeden değişikliklerin görüntülenmesi.

 

Yukarıdada görültüğü üzere ControlID özelliğinde btn_ok seçilmiş ve yine EventName özelliğindede Click eventi seçilmiş. Bunun nedeni ise Trigger tetiklemesinin Butonumuza tıklandığında olacak olması. Yani Butona tıklandığında Update Panel içeriği güncellenecek.

Tüm bu işlemleri yaptığımıza göre artık dbye veri girişi yapabiliriz.  Adınızı ve email adresinizi girip Tamam butonuna bastığınızda Aşağıda bulunan gridview nesnesinin yenilendiğini ve eklediğiniz verinin burada göründüğünü göreceksiniz. Yani update panel içeriğinin yenilendiğini görüyoruz. Aşağıda verilen resim ekleme işlemi yapıldıktan sonra alınan görüntüyü vermektedir.

 

Bu günlük bu kadar makalemizin devamında UPDATE işlemlerinin nasıl yapılacağını ve QueryString özelliğini inceleyeceğiz.

{ Mehmet KURT || Yazılım Geliştirme Uzmanı }
Mehmet.kurt@mspro.org

 

 

 

Sql tarafındaki verilerimizi c# kullanarak xml olarak dosya oluşturma işlemleri
.

Makalemiz boyunca Okul database kısmındaki öğrenci tablomuz içerisindeki verilerimizi
alıp bu verilerimizi xml olarak belirlediğimiz yere saklayacağız .

Okul database imiz için gerekli olan database yapısı aşağıdaki gibidir .

create database Okul

use Okul

create table Ogrenciler

(

id int identity(1,1),

Ad nvarchar(20),

Soyad nvarchar(20),

Adres nvarchar(70),

VeliAdi nvarchar(20),

TelefonNumara nvarchar(20),

EDiplomaNot int,

constraint PK_Ogrenciid primary key(id)

)

Yukarıdaki tanımlamalarda SQL server tarafında örnek database ve tablomuzu oluşturduk
. Simdi c# tarafında işlemlerimizi gerçekleştirelim.

App.config

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<connectionStrings>

<add name="Baglan" connectionString="data source=.; initial
catalog = Okul; integrated security = true"/>

</connectionStrings>

</configuration>

Yukarıdaki tanımlamada app.config dosyası oluşturarak database bağlantı yolumuzu
belirledik .

C# içerisinde bu bağlantımızı kullanmak için Add Referance… kısmından System.Configuration
uygulamamıza implement etmemiz gerekir .

Simdi Ogrenci.cs kısmını oluşturalım . bu class olusturmamızın nedeni sql tarafından
gelen verileri list<> generic bir koleksiyona atarken list<> koleksiyonun
tipini belirlemek içindir.

namespace OgrenciSerilestir

{

[Serializable ]

public class Ogrenci

Ogrenci class ımıza başlamadan önce Ogrenci class ımızı public olarak belirlememiz
ve

[Serializable] seklinde bildirmemiz gerekir.

Ogrenci.cs

string _ad, _soyad, _adres, _veliadi, _telno;

int _diplomanot;

public string Ad

{

get{return this._ad;}

set{this._ad = value;}

}

public string Soyad

{

get { return this._soyad; }

set { this._soyad = value; }

}

public string Adres

{

get { return this._adres; }

set { this._adres = value; }

}

public string VeliAdi

{

get { return this._veliadi; }

set { this._veliadi = value; }

}

public string TelefonNumarasi

{

get { return this._telno; }

set { this._telno = value; }

}

public int DiplomaNot

{

get { return this._diplomanot; }

set { this._diplomanot = value; }

}

Yukarıdaki tanımlamalarda kapsülleme kullanarak değişkenlerimiz ve veri akışı
kısmını kapsül ledik. Bunu yapmamızın nedeni ilerde verinin burada bir şekilde
kontrol edilme istegine cevap vermek adına ileriye yönelik bir çalışmadır .

public Ogrenci()

{

}

public Ogrenci(string ad, string soyad, string adres , string veliad, string
telno, int Dnot)

{

this.Ad = ad; this.Soyad = soyad; this.Adres = adres; this.VeliAdi = veliad;
this.TelefonNumarasi = telno; this.DiplomaNot = Dnot;

}

İki adet yapıcı metot tanımlaması gerçekleştirdik. ilk yapıcı metodumuz bos
olarak belirledik bunun nedeni xml olarak serileştireceğimiz zaman bir adet
boş yapıcı metot a ihtiyaç duymasıdır. Bu kısım çok önemlidir. Tüm kodlarımız
doğru bile olsa eğer boş bir yapıcı metot tanımlamadı isek yordamımız çalışmayacaktır.

Ardından normal yapıcı metodumuzu oluşturarak tipimize gelen verilerimizi property
tanımlamalarımızı kullanarak aktardık.

public override string ToString()

{

return string.Format("Adı : {0} Soyadi : {1} Adres {2} Veli Adi {3} Telefon
Numarasi {4} Diploma notu {5}", Ad, Soyad, Adres, VeliAdi, TelefonNumarasi,
DiplomaNot);

}

ToString () metodunu ezdik buradaki amacımız ise ToString() gibi hazır bir
metodumuz var diye düşünüp bu metodu bilgi ver seklinde kullanma isteğimizdir.

Yardimci.cs : bu class ımız bağlantı işlemlerimiz verileri aktarma ve xml ile
işleme kısmının bulunduğu kısımdır.

Kullandığımız isim alanları ve açıklamaları.

using System.Data.SqlClient; — Database ile işlemler yapmak için

using System.Configuration; — Olusturduğumuz app.config bağlantı ayar dosyamızı
connectionString olarak tanımlamak için

using System.IO; — Xml dosya olusturmak icin vericegimiz yol tanımını almak
ve olusturmak için kısacası dosyalama işlemleri için .

using System.Xml.Serialization; — Adından da anlaşılacağı gibi xml olarak
serilestirme işlemi icin gerekli olan kısım

SqlConnection con;

SqlCommand cmd;

Tanımlamamızda namespace kısmında SqlConnection ve SqlCommand tipinde iki adet
değişken olurduk tüm class içinde ihtiyaç duyduğumuz an çağırmak için en tepede
yani namespace kısmında belirledik .

public Yardimci()

{

con = new SqlConnection(ConfigurationManager.ConnectionStrings["Baglan"].ConnectionString);

}

Yardimci Kullan = new Yardimci () seklinde bir örnekleme kısmı olduğu zaman
yukarıdaki yapıcı metot çalışacaktır ve bağlantı yolumuzu köprülenecektir.

Bağlantı tanımlamamızda kullandığımız ConfigurationManager.ConnectionStrings["Baglan"].ConnectionString
tanımlamasında Syste.Configuration namespace ini en basta using ile uygulamamıza
belirttiğimiz için direk olarak eristik app.config kısmında tanımladığımız yol
tanımını string olarak belirlememizi sağladı bunun amacı pek çok yerde yol bağlantı
ayarlarını almak ve kullanmak zorunda isek bu şekilde app.config içerisine tanımlama
yapılarak connection name(ConnectionStrings["Baglan"] ) ismi ile çağrılabilinir
bu şekilde herhangi bir değişim olduğu zaman merkezi olarak yönetilebilirliği
sağlamak amacı ile yapılmıştır.

void BaglantiYonetimi()

{

if (con.State == System.Data.ConnectionState.Open)

{

con.Close();

}

else

{

con.Open();

}

}

Yordamımız içerisinde bağlantımızı pek çok kez açmak ve kapamak isteyebiliriz
ve doğal olarak en son bağlantımızı nasıl bıraktığımızı hatırlamak için kodumuzun
ilgili yerine bakmak zorunda kalırız . Bunu önlemek amacı ile BaglantiYonetimi
adında bir private metot kullanarak bağlantı durumunu if yapısını kullanarak
kontrol ettirip acık ise kapatılmasını kapalı ise açılmasını metot olarak yazmak
bize çalışma zamanında rahat bir yapı kazandıracaktır. Burada bağlantının durumları
Open ve Close ile sınırlı değildir. Bir çok durum için bu yapıyı daha da dallandırarak
kullanabiliriz.

public List<Ogrenci> OgrencileriAl()

{

List<Ogrenci> ogrencilerim = new List<Ogrenci>();

cmd = new SqlCommand("select Ad,Soyad,Adres,VeliAdi,TelefonNumara,EDiplomaNot
from Ogrenciler", con);

BaglantiYonetimi();

SqlDataReader dr = cmd.ExecuteReader();

while (dr.Read())

{

ogrencilerim.Add(new Ogrenci(dr["Ad"].ToString(), dr["Soyad"].ToString(),
dr["Adres"].ToString(), dr["VeliAdi"].ToString(), dr["TelefonNumara"].ToString(),
(int)dr["EDiplomaNot"]));

}

BaglantiYonetimi();

return ogrencilerim;

}

OgrencileriAl metodumuzu kullanarak database ilgili tabloya bağlanıp verilerimizi
çekeriz ve bunları daha önceden oluşturduğumuz ogrenci tipine koleksiyona değer
olarak belirterek içerisine aktarırız List<ogrenci> seklinde .

Simdi metodumuzu biraz açıklayalım …

1 . List<Ogrenci> ogrencilerim = new List<Ogrenci>(); şeklinde
bir list<> generic koleksiyon oluşturduk ve bu list generic koleksiyonumuzun
sadece öğrenci tipi veya bu tip den türetilmiş tipleri kabul etmesini istediğimizi
belirledik ama biz bu uygulamada herhangi bir kalıtım kullanmadığımız için burada
öğrenci tipi için geçerlidir.

2. cmd = new SqlCommand("select Ad,Soyad,Adres,VeliAdi,TelefonNumara,EDiplomaNot
from Ogrenciler", con);

BaglantiYonetimi();

Cmd sqlcommand içerisine tsql komutumuzu yazdık normal şartlarda bu şekilde
tsql kodun uygulama içerisine yazılması önerilmez bunun yerine ogrencilerilistele
adında bir procedure SQL tarafında oluşturulur ve bu procedure nin geri dönüş
değerlerine göre yakalanıp uygulamaya aktarılır ama bizim amacımız burada xml
olarak serileştirme işlemini anlatmak bir başka makalemde bu kısma detaylı olarak
değineceğiz derinlemesine araştıracağız!

BaglantiYonetimi metodumuzu kullanarak bağlantımızı kontrol ettik bu durumda
bağlantımızı hiç open etmediğimiz için bağlantımız açılacaktır.

3 . SqlDataReader dr = cmd.ExecuteReader();

SqlDataReader tipinden dr adında bir değişken belirledik ve cmd sqlcommand
mızı execute.read() komutunu vererek sql sorgumuzun tüm sonucunu dr attık .
SqlDataReader kamyon gibi düşüne bilirsiniz tüm verileri yüklendi ama bu verileri
bir baksa yere boşaltmadan kullanamayız SqlDataReader sadece verileri gider
alır gelir. Bağlantımızı köprü SqlDataReader ımızıda kamyon gibi düşünün .

4 . while (dr.Read())

{

ogrencilerim.Add(new Ogrenci(dr["Ad"].ToString(), dr["Soyad"].ToString(),
dr["Adres"].ToString(), dr["VeliAdi"].ToString(), dr["TelefonNumara"].ToString(),
(int)dr["EDiplomaNot"]));

}

BaglantiYonetimi();

return ogrencilerim;

}

While döngüsünü kullanarak Sqldatareader tipindeki dr değişkenimizin son satırına
kadar döngümüzü çalışmasını sağladık .

Şimdi kamyonumuzdaki ( SqldataReader ) içerisindeki verilerimizi List<ogrenci>
tipindeki öğrencilerim koleksiyonuna ekleme sırası geldi ve öğrencilerim.add(
dr[“Ad”].toString() seklinde tüm kolonlarımızı yazarak koleksiyonumuza ekledik
ve daha sonra bağlantı yönetimi metodumuzu kullanarak bağlantımızı kapattık
.

Burada önemli olan tek kural bağlantıyı ihtiyacımız olduğu zaman açmak işimiz
bittiği zaman kapatmak olacaktır . bu şekilde çalışır isek yordamımız için daha
fazla güç harcanmaz.

Return ogrencilerim ile metodumuz dışına koleksiyonumuzu aktardık.

5 . public void XmlSerilestir(List<Ogrenci> GelenOgrenciler, string Path)

{

XmlSerializer seriliazer = new XmlSerializer(typeof(List<Ogrenci>));

FileStream YolTanimi = new FileStream(Path, FileMode.Create);

seriliazer.Serialize(YolTanimi, GelenOgrenciler);

YolTanimi.Close();

Console.WriteLine("Basarili Oldu");

}

Ve xml serileştirme metodumuz. metodumuz bizden List<ogrenci> tipinden
GelenOgrenciler ve string tipinden Path tanımı istemektedir.

XmlSerializer seriliazer = new XmlSerializer(typeof(List<Ogrenci>));
kısmında örneklememizi yaptık .

FileStream YolTanimi = new FileStream(Path, FileMode.Create); filestream ile
bir kanal açtık ve Path tanımına gelen c:ogrenci.xml adı için filemode.create
kısmında adı verilen yola adı verilen dosyayı açma kısmını tanımladık .

seriliazer.Serialize(YolTanimi, GelenOgrenciler); bölümünde xml çevirme işlemimiz
tamamlanmıştır. Artık tek yapmamız gereken

YolTanimi.Close();

İle kanalımızı kapatmak tır.

Makalemiz boyunca sql server tarafında bir tabloya bağlanarak bilgileri alıp
xml e çevirme işlemi anlatılmıştır .

Umarım yararı olmuştur .

Excel ve Ado.Net
 
Bu yazimda Ado.Net ile Excel’i aynen veritabani gibi kullanip veri getirme yöntemine deginecegiz.
 
Klasik yöntemlerle excelden veri okumak ve yazmak ugrastirici olablmektedir ama Ado.Net’e hakimseniz bir iki ufak noktaya dikkat ederek, Ado.Net ile Excel’de veri okuma, veri ekleme ve güncelleme çok kolay hale gelmektedir.
 
Simdi ise koyulalim.
 
1.Adim: Bir adet Visual Studio Projesi olusturunuz.
 
2.Adim: Bir adet Excel Dökümani olusturun ve adini deneme.xls (deneme.xlsx) birakin. Bu excel dosyasini Visual Studio projenizin debug klasörünün içerisine birakiniz.
 
3.Adim: Form1’e 1 adet DataGridView, 3 adet Button ekleyiniz.
 
4.Adim: Projenizde Project/Add Class ile bir adet class olusturunuz. Ben ismini Class1 olarak biraktim.
 
5.Adim: Class1.cs sayfasini açiniz ve içerisine asagidaki kodlari ekleyiniz.
 
Eger Excel 2007 kullaniyorsaniz connection stringi asagidaki biçimde düzeltiniz.
OleDbConnection baglanti = new OleDbConnection("Data Source=deneme.xlsx;Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0");
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb; //Sizde Ekleyiniz.
using System.Data; //Sizde Ekleyiniz.
 
namespace WindowsFormsApplication9
{
    class Class1
    {
 
        OleDbConnection baglanti = new OleDbConnection("Data Source=deneme.xls;Provider=Microsoft.jet.OLEDB.4.0;Extended Properties=Excel 8.0");
        OleDbCommand komut;
 
        public DataTable ExcelVerileriniGetir() //Veri Okuma
        {
            komut = new OleDbCommand("select * from [Sayfa1$]",baglanti);
            if (baglanti.State == ConnectionState.Closed)
            {
                baglanti.Open();
            }
            OleDbDataReader oku = komut.ExecuteReader();
            DataTable dt = new DataTable();
            dt.Load(oku);
            return dt;
        }
 
        public void KayitYap(string adi,string soyadi) //Yeni Kayit Ekleme
        {
            komut = new OleDbCommand("insert into [Sayfa1$] values (@adi,@soyadi)", baglanti);
            komut.Parameters.Add("@deger1",OleDbType.VarChar,50).Value=adi;
            komut.Parameters.Add("@deger2", OleDbType.VarChar, 50).Value = soyadi;
            if (baglanti.State == ConnectionState.Closed)
            {
                baglanti.Open();
            }
            komut.ExecuteNonQuery();
        }
 
        public void KayitGuncelle(string DegisecekAd,string DegistirilecekAd) //Kayit Güncelleme
        {
            komut = new OleDbCommand("update [Sayfa1$] set ADI=@DegisecekAd where ADI=@DegistirilecekAd", baglanti);
            komut.Parameters.Add("@DegisecekAd", OleDbType.VarChar, 50).Value = DegisecekAd;
            komut.Parameters.Add("@DegistirilecekAd", OleDbType.VarChar, 50).Value = DegistirilecekAd;
            if (baglanti.State == ConnectionState.Closed)
            {
                baglanti.Open();
            }
            komut.ExecuteNonQuery();
        }
 
    }
}
 
Burada tüm kullanim normal veri tabanlarina benzemektedir. Dikkat etmeniz gereken nokta yani normal veritabanlarindan farklilik gösteren noktalar;
 
  • Connection String de ki Extended Properties özelligi,
  • OledbCommand nesnesindeki sql komutunda excel sayfalarinin “[]” içerisine konulup sayfa isminin sonuna “$” isareti getirilmesidir. Bizde [Sayfa1$] seklinde olduguna dikkat ediniz.
Simdi formunuza gelerek her bir butonun Click Eventine;  
       
        Class1 yeni = new Class1(); //Class1 den yavru degisken türetildi.
       
        private void button1_Click(object sender, EventArgs e)
        {
            dataGridView1.DataSource = yeni.ExcelVerileriniGetir();
            //Veriler DatagridView’e aktarildi.
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            yeni.KayitYap("Gülser","Demirog");
            //Yeni Kayit ekleniyor.
        }
 
        private void button3_Click(object sender, EventArgs e)
        {
            yeni.KayitGuncelle("Gözde","Nafiye");
            //Kayit Güncceleme islemi,Nafiye isimleri Gözde oldu.
        }
 
Diger yazilarimda görüsmek üzere.
 
Engin Demiroğ
MCSE-MCSD.NET
engin@e-learner.net