Microsoft firması 2002 yılında .NET Framework adı verilen sınıf kitaplığını hazırlayıp kullanıma sunduktan sonra daha önce veritabanı işlemleri için ADO’yu kullananlar süratle ADO.NET’e geçtiler. .NET uyumlu uygulamalarda veritabanı işlemleri için ADO’yu kullanmak mümkün olsa bile bu önerilmemektedir. Her ne kadar Türkiye’de Visual Basic uygulamalarında veritabanı işlemleri hakkında ilk kapsamlı bilgileri 1995 yılında yayınlanan Visual Basic 3.0 kitabımla okurların istifadesine sunmuş olsam bile ADO teknolojisi Microsoft tarafından çok sonra geliştirilip kullanıma sunuldu.
Şimdi izninizle yıllar önce yayınlanan Visual Basic 5.0 ve 2003 yılında yayınlanan Visual Basic .NET kitabımdan yararlanıp C# uygulamaları dahilinde ADO teknolojisi ile Access veritabanları üzerinde nasıl işlem yapıldığını kısaca anlatacağım. Nedense 2003 yılında yayınlanan Visual Basic .NET kitabımda SqlDbDataAdapter sınıfını ve bu sınıfın Fill() metodunu kullanıp veritabanından DataSet’e veri çekmem kabahat olarak görülmemesine rağmen Visual Basic .NET kitabım için hazırladığım metni ve birkaç satırlık kodu C#’a uyarlayıp 2004 yayınlanan C# kitabımda kullanınca bazılarına göre suç işlemiş oldum.
Yukarıda işaret edildiği üzere .NET uygulamalarında veritabanı işlemlerini ADO.NET adı altında gruplanan sınıflardan yararlanarak yapmak önerilmektedir. ADO.NET teknolojisinin önemli sınıflarından ikisi OleDbDataAdapter ve SlqDataAdapter’dir. 2004 yılında yayınlanan C# kitabımda OleDbDataAdapter sınıfının Fill() metodunu kullanıp bir tablonun içeriğini DataSet’e aktarmış olmam suçlanmama neden olduğu için bu konulara yabancı olmadığımı, yani DataSet, SqlDataAdapter vs sınıfları hakkında az çok bilgi sahibi olduğumu kanıtlamak olduğundan DataAdapter’den söz etmek yerine önceliği ADO teknolojisine verdim.
Eski Visual Basic kaynaklı ADO teknolojisi hakkında bilgi hakkında bilgi verebilmek için Visual Studio ile yeni bir proje hazırlayıp ekrana Add Reference diyalog kutusunu getirdim.

Bu diyalog kutusunda Microsoft ActiveX Data Objects’i seçip OK düğmesini tıklayarak bu referansın Solution Explorer penceresinde listelenmesini sağladım. Başka bir deyişle bu referanstaki sınıflardan yararlanmak istediğimi Visual Studio’ya söylemiş oldum. ADO ile ilgili referansın Solution Explorer penceresinde listelenmesini sağladıktan sonra projenin başlangıç formunun Load olayını temsil eden metotta aşağıdaki gibi bir Connection nesnesi hazırladım.
private void Form1_Load(object sender, EventArgs e)
{
ADODB.Connection Baglanti = new ADODB.ConnectionClass();
}
Bu şekilde Connection nesnesi hazırladıktan sonra şimdi sırada Open() metodu ile veritabanına bağlanmak var. Connection sınıfının Open() metodu 4 parametreye sahiptir ve ilk parametre ile bağlantı metni verilmektedir. Olası veritabanı adı benzerliği(!) kabahatini işlememek için kendim bir veritabanı hazırlamak yerine bazı programlama dilleri ile birlikte verilen "dbdemos" adlı Access veritabanını kullanacağım.
private void Form1_Load(object sender, EventArgs e)
{
ADODB.Connection Baglanti = new ADODB.ConnectionClass();
string str = "PROVIDER=Microsoft.Jet.OLEDB.4.0;
Data Source=C:\\Dosyalar\\Stok.mdb;";
Baglanti.Open(str, "Admin", "", 0);
}
Bu kod sayesinde Access veritabanına bağlandıktan sonra RecordSet nesnesi hazırlayacağım. RecordSet nesnesini nasıl hazırladığımı aşağıda görebilirsiniz. Recordset sınıfının yapıcı metodu herhangi bir parametreye sahip değildir.
private void Form1_Load(object sender, EventArgs e)
{
ADODB.Connection Baglanti = new ADODB.ConnectionClass();
string str = "PROVIDER=Microsoft.Jet.OLEDB.4.0;
Data Source=C:\\Dosyalar\\Dbdemos.mdb;";
Baglanti.Open(str, "Admin", "", 0);
ADODB.Recordset kayit_set = new ADODB.Recordset();
}
Bu RecordSet nesnesine Connection nesnesi ile bağlanılan Access veritabanındaki bir tablonun içeriğini aktarmak için RecordSet nesnesini Open() metodu ile açmak gerekiyor. Veritabanından veri çekerken gerek duyulacak SQL kodunu Open() metoduna parametre olarak verebilirsiniz. Open() metodu ile dbdemos.mdb adlı Access veritabanındaki "Customer" adlı tablodaki bütün kayıtları RecordSet’e aktarmak için yukarıda verdiğim koda ekleme yaptım.
private void Form1_Load(object sender, EventArgs e)
{
ADODB.Connection Baglanti = new ADODB.ConnectionClass();
string str = "PROVIDER=Microsoft.Jet.OLEDB.4.0;
Data Source=C:\\Dosyalar\\dbdemos.mdb;";
Baglanti.Open(str, "Admin", "", 0);
ADODB.Recordset kayit_set = new ADODB.Recordset();
kayit_set.Open("SELECT * FROM customer", Baglanti,
ADODB.CursorTypeEnum.adOpenDynamic,
ADODB.LockTypeEnum.adLockOptimistic, 0);
}
Bu andan itibaren ilgili veritabanın ilgili tablosunun bütün içeriği RecordSet’te bulunmaktadır. Programcı Recordset’in içeriğini istediği gibi değerlendirebilir, istediği işlemi yapabilir. ADO.NET adı altında gruplanan sınıflardan birisi olup .NET Framework ile gelen Dataset sınıfı Recordset ile benzer işleve sahip olsalar bile birbirinden oldukça farklıdırlar. Bu makalede asıl amacım xxxDataAdapter sınıfından söz etmek olduğu için Recordset ile Dataset sınıflarının farklılıklarının üzerinde durmayacağım. Bu projede çalıştırıldığında içeriğini Recordset’e aktardığım tablonun ilk kaydının yani Recordset’teki ilk satırın içeriğini formun üzerinde görüntülemek için forma birkaç TextBox yerleştirdim ve yukarıda verdiğim kod şu satırları ekledim.
textBox1.Text = kayit_set.Fields["CustNo"].Value.ToString();
textBox2.Text = kayit_set.Fields["Company"].Value.ToString();
textBox3.Text = kayit_set.Fields["Addr1"].Value.ToString();
textBox4.Text = kayit_set.Fields["Addr2"].Value.ToString();
textBox5.Text = kayit_set.Fields["City"].Value.ToString();
Bu satırlar yukarıda verilen Form1_Load metoduna yazılıp proje çalıştırılırsa RecordSet’teki ilk satırın işaret edilen 5 alanın içeriği TextBox’lara aktarılır. RecordSet’teki bir sonraki satırın içeriğini TextBox’larda görüntülemek istendiğinde RecordSet sınıfının MoveNext metodu kullanılmaktadır.
Form’un Load olayını temsil eden metotta hazırladığım RecordSet nesnesini Form1 sınıfının başka metotlarında kullanabilmek için değişken tanımlama satırını Fom1_Load metodunun dışına alıp aşağıda verdiğim kodu yazdım.
private void Sonraki_Click(object sender, EventArgs e)
{
kayit_set.MoveNext();
if (!kayit_set.EOF)
{
textBox1.Text = kayit_set.Fields["CustNo"].Value.ToString();
textBox2.Text = kayit_set.Fields["Company"].Value.ToString();
textBox3.Text = kayit_set.Fields["Addr1"].Value.ToString();
textBox4.Text = kayit_set.Fields["Addr2"].Value.ToString();
textBox5.Text = kayit_set.Fields["City"].Value.ToString();
}
else
{
MessageBox.Show("Tablonun sonundasınız");
}
}
Recordset sınıfının MoveNext, MoveFirst, MovePrevious ve MoveLast metotlarından yararlanıp satırların, dolayısıyla ilgili tablonun kayıtları arasında dolaşmak mümkündür. Varsayalım ki bu konuları bilmiyorum: Bu durumda yıllar önce yayınlanan Visual Basic 5 kitabımdan yararlanıp RecordSet sınıfı hakkında en az 20 sayfa yazabilirim. Bu makalede asıl amacım xxxDataAdepter sınıfı hakkında bilgi sahibi olduğumu, başka bir deyişle herhangi bir yerli kaynaktan Fill() metodunun nasıl kullanıldığı konusunda çalıntı yapmadan kullanabildiğimi cümle aleme göstermek olduğundan için Recordset sınıfı üzerinde konuşmayı burada kesiyorum. Bu düşünce ile Visual Studio ile yeni bir C# projesi hazırlayıp Toolbox’tan yararlanıp forma bir OleDbConnection nesnesi yerleştirdim.
Eğer amacım SqlServer veritabanı üzerinde işlem yapmak olsaydı .NET Framework ile gelen OleDbConnection sınıfı yerine SqlConnection sınıfından yararlanırdım. Her ne kadar OleDbConnection sınıfı ile SQL Server veritabanlarına bağlanmak mümkün olsa bile kullanılması önerilmiyor.
Access veritabanlarına bağlanılırken yararlanılan OleDbConnection nesnesini Toolbox’tan yararlanarak hazırlamak yerine bu işlem için kod yazabilirsiniz. Forma OleDbConnection nesnesini yerleştirdikten sonra sıra bu nesnenin ConnectionString özelliğini ayarlamaya gelir. Bu işlem için daha önce Visual Studio’nun Server Explorer penceresinde ilgilendiğim veritabanı için bağlantı hazırlayıp OleDbConnection nesnesinin ConnectionString özelliğini kolayca ayarlayabilirdim ama amacım OleDbDataAdapter sınıfı ve bu sınıfın Fill() metodu hakkında az çok bilgim olduğunu muhtelif kişilere göstermek olduğu için yıllar önce yayınlanan Visual Basic .NET kitabımdan yararlanıp kod yazarak OleDbConnection nesnesinin ConnectionString özelliğini ayarlayacağım. .NET uyuumlu ilk Visual Basic kitabımla ilgili olarak henüz herhangi bir çalıntı iddiası olmadığı Visual Basic .NET kitabımda OleDbConnection sınıfıyla ilgili olarak yazdığım kodları C#’a uyarladım.
private void Form1_Load(object sender, EventArgs e)
{
string Baglanti_metni;
string Segment1, Segment2, Segment3;
Segment1 = "Provider=Microsoft.Jet.OLEDB.4.0;";
Segment2 = "Data Source=C:\\Dosyalar\\dbdemos.mdb;";
Segment3 = "User Id=Admin";
Baglanti_metni = Segment1 + Segment2 + Segment3;
oleDbConnection1.ConnectionString = Baglanti_metni;
oleDbConnection1.Open();
}
Bu kodda forma yerleştirdiğim OleDbConnection nesnesinin ConnectionString özelliğini ayarladıktan sonra Open() metodu ile açtım. Bu andan itibaren yani bağlandığımız veritabanı üzerinde istediğimiz işlemi yapabiliriz. Microsoft firması programcılar veritabanları üzerinde kolayca işlem yapsınlar diye .NET Framework ile birlikte OleDbDataAdapter adında bir sınıf vermektedir. Başka bir deyişle veritabanı işlemleri için OleDbDataAdapter sınıfından yararlanmak şart değildir ama kullanılması önerilmektedir. Hatta bazı programcılar Microsoft tarafından geliştirilen OleDbDataAdapter sınıfından yola çıkıp kendi Adapter sınıflarını hazırlıyorlar. Madem konumuz OleDbDataAdapter sınıfıdır bende Toolbox’tan yararlanıp forma bir OleDbDataAdapter nesnesi yerleştirdim.
Toolbox’tan yararlanılıp forma OleDbDataAdapter nesnesi yerleştirilir yerleştirilmez Visual Studio ile gelen Data Adapter Configuration Wizard kendiliğinden çalışmaya başlamaktadır. Bu Wizard sayesinde OleDbDataAdapter nesnesinin özellikleri kolayca ayarlanabilmektedir.
Wizard ile OleDbDataAdapter nesnesinin özelliklerini ayarlamak kolay olduğu için benim bu sınıfın Fill() metodunu kullanmayı bildiğime delalet edemez. Bu nedenle bu diyalog kutusundaki Cancel düğmesini tıklayıp Wizard’ın çalışmasını sona erdirdim. Özel bir nedeniniz yoksa DataAdapter nesnesinin özelliklerini ayarlarken Wizard’dan yararlanmanız önerilir.
OleDbDataAdapter nesnesi temelde veritabanından verileri çekip Dataset’te bir DataTable’a yerleştirmektedir. DataSet’te yapılan değişiklikleri yani kayıt ekleme, silme ve değiştirme işlemlerini veritabanına yansıtmaktadır. Başka bir deyişle OleDbDataAdapter’dan yararlanmak istiyorsanız DataSet nesnesine ihtiyacınız olacaktır. DataSet nesnesini kod yazarak hazırlayabilir veya Toolbox’tan yararlanıp forma yerleştirebilirsiniz. DataSet nesnesi hazırlarken kod yazmayı tercih ettim. Bu amaçla yukarıda verdiğim kodu ekleme yaptım. "Veri_set" adını verdiğim(umarım Dataset sınıfının örneğini hazırlarken nesne adı seçerken değişken adı çalmamışımdır) nesneyi Form1 sınıfının bütün metotlarında kullanabilmek için değişken tanımlamayı metodun dışında yani Class bloğu içinde yaptım.
DataSet veri_set;
private void Form1_Load(object sender, EventArgs e)
{
veri_set = new DataSet();
string Baglanti_metni;
string Segment1, Segment2, Segment3;
Segment1 = "Provider=Microsoft.Jet.OLEDB.4.0;";
Segment2 = "Data Source=C:\\Dosyalar\\dbdemos.mdb;";
Segment3 = "User Id=Admin";
Baglanti_metni = Segment1 + Segment2 + Segment3;
oleDbConnection1.ConnectionString = Baglanti_metni;
oleDbConnection1.Open();
}
Bu hazırlıklardan sonra ilgilendiğim tablonun yapısına uygun olarak bir DataSet’te bir DataTable hazırlayıp uzun uğraşlar sonucu istediğim satırları bu DataTable’a aktarabilirdim. Ancak Microsoft’un programcıları oturmuşlar Fill() adında bir metot hazırlamışlar ve programcılar tabloların içeriğini kolayca DataSet’e aktarabiliyorlar. Her ne kadar Fill() metodu programcının yazması gereken kodu oldukça kısaltsa bile Fill() metodunu kullandım diye suçlanacağımı bilseydim kendim bir DataAdapter sınıfı hazırlayıp kullanırdım.
OleDbDataAdapter sınıfının Fill() metodu veritabanından verileri alıp DataSet’te bir DataTable nesnesine aktarırken SQL kodu kullanacağı için Command nesnesine gerek duyar. Eğer OleDbDataAdapter nesnesinin özelliklerini Data Adapter Configuration Wizard sayesinde ayarlamış olsaydım Wizard gerek duyulacak Command nesnesini otomatik olarak hazırlardı. Command nesnesini kod yazarak hazırlayabilir veya Toolbox’tan yararlanarak forma yerleştirebilirsiniz. Kendim Toolbox’tan yararlandım
Aslında Wizard’ın çalışması hemen sonlandırılsa bile gerek duyulacak command nesneleri otomatik olarak hazırlanıyor. Amacım Fill() metodunu kullanmayı bildiğime bazı insanları inandırmak olduğu için Command nesnesini kendim hazırlamayı tercih ettim.

Toolbox’tan yararlanıp forma OleDbCommand nesnesini yerleştirdikten sonra ilk olarak CommandText özelliğini ayarlayıp veritabanından veri çekilirken kullanılacak SQL kodunu yazmak gerekir. Madem Fill() metodu veritabanından bilgi çekilirken kullanılıyor hazırlanacak Command nesnesinin CommandText özelliğine içinde SELECT deyimi olan bir SQL cümlesini yazıp aktarmak gerekir. OleDbCommand nesnesinin CommandText özelliğini ayarlarken Properties penceresinden yararlanabilir veya bu işlem için kod yazabilirsiniz. Kendim CommandText özelliğini kod yazarak ayarlamak istediğim için yukarda verdiğim koda aşağıdaki gibi ekleme yaptım.
DataSet veri_set;
private void Form1_Load(object sender, EventArgs e)
{
veri_set = new DataSet();
string Baglanti_metni;
string Segment1, Segment2, Segment3;
Segment1 = "Provider=Microsoft.Jet.OLEDB.4.0;";
Segment2 = "Data Source=C:\\Dosyalar\\dbdemos.mdb;";
Segment3 = "User Id=Admin";
Baglanti_metni = Segment1 + Segment2 + Segment3;
oleDbConnection1.ConnectionString = Baglanti_metni;
oleDbConnection1.Open();
oleDbCommand1.CommandText = "SELECT * FROM Customer";
oleDbCommand1.Connection = oleDbConnection1;
}
Command nesnesinin CommandText özelliğini ayarladıktan sonra bu Command nesnesinin yararlanacağı Connection nesnesinin adını Connection özelliğine aktardım. Bütün bu hazırlıklardan sonra artık OleDbDataAdapter sınıfının Fill() metodunu kullanabiliriz. Bu metodu nasıl kullandığımı aşağıda görebilirsiniz. Doğrusunu söylemek gerekirse Fill() metodunun nasıl kullanıldığı benim buluşum değil.
DataSet veri_set;
private void Form1_Load(object sender, EventArgs e)
{
veri_set = new DataSet();
string Baglanti_metni;
string Segment1, Segment2, Segment3;
Segment1 = "Provider=Microsoft.Jet.OLEDB.4.0;";
Segment2 = "Data Source=C:\\Dosyalar\\dbdemos.mdb;";
Segment3 = "User Id=Admin";
Baglanti_metni = Segment1 + Segment2 + Segment3;
oleDbConnection1.ConnectionString = Baglanti_metni;
oleDbConnection1.Open();
oleDbCommand1.CommandText = "SELECT * FROM Customer";
oleDbCommand1.Connection = oleDbConnection1;
oleDbDataAdapter1.Fill(veri_set, "customer");
}
OleDbDataAdapter sınıfının Fill() metodunun aşırı yüklenmiş 7 farklı sürümü bulunmaktadır. Burada 2 parametreli sürümünü kullandım. 1. parametrede Dataset’in, ikinci parametrede ise işaret edilen Dataset’te hazırlanacak DataTable adını verdim. Ancak bu şekilde kullanılan Fill() metodu hataya neden olur. Çünkü Fill() metodu adı OleDbDataAdapter nesnesinin SelectCommand özelliğine aktarılmış Command nesnesinin SQL kodlarını işletmek ister. Yukarıda OleDbDataAdapter nesnesinin bu özelliğini henüz ayarlamadığımız için hata meydana gelir. Bu hatanın önüne geçmek için bu koda bir satır ekledim.
DataSet veri_set;
private void Form1_Load(object sender, EventArgs e)
{
veri_set = new DataSet();
string Baglanti_metni;
string Segment1, Segment2, Segment3;
Segment1 = "Provider=Microsoft.Jet.OLEDB.4.0;";
Segment2 = "Data Source=C:\\Dosyalar\\dbdemos.mdb;";
Segment3 = "User Id=Admin";
Baglanti_metni = Segment1 + Segment2 + Segment3;
oleDbConnection1.ConnectionString = Baglanti_metni;
oleDbConnection1.Open();
oleDbCommand1.CommandText = "SELECT * FROM Customer";
oleDbCommand1.Connection = oleDbConnection1;
oleDbDataAdapter1.SelectCommand = oleDbCommand1;
oleDbDataAdapter1.Fill(veri_set, "customer");
}
Bu andan itibaren DataSet’teki DataTable’in içeriği üzerinde istenen işlem yapılabilir. Yukarıdaki sayfalarda RecordSet’in bir satırının içeriğini TextBox’lara aktarmıştık. Genel alışkanlık DataTable’ın içeriğini DataGridVied’de görüntülemek olsa bile DataRow nesnesi hazırlayıp DataTable’ın ilk satırın içeriğini TextBox’lara aktardım.
DataSet veri_set;
private void Form1_Load(object sender, EventArgs e)
{
veri_set = new DataSet();
string Baglanti_metni;
string Segment1, Segment2, Segment3;
Segment1 = "Provider=Microsoft.Jet.OLEDB.4.0;";
Segment2 = "Data Source=C:\\Dosyalar\\dbdemos.mdb;";
Segment3 = "User Id=Admin";
Baglanti_metni = Segment1 + Segment2 + Segment3;
oleDbConnection1.ConnectionString = Baglanti_metni;
oleDbConnection1.Open();
oleDbCommand1.CommandText = "SELECT * FROM Customer";
oleDbCommand1.Connection = oleDbConnection1;
oleDbDataAdapter1.SelectCommand = oleDbCommand1;
oleDbDataAdapter1.Fill(veri_set, "customer");
DataRow Satir;
Satir = veri_set.Tables["customer"].Rows[0];
textBox1.Text = Satir["CustNo"].ToString();
textBox2.Text = Satir["Company"].ToString();
textBox3.Text = Satir["Addr1"].ToString();
textBox4.Text = Satir["Addr2"].ToString();
textBox5.Text = Satir["City"].ToString();
}
Tabii ki DataAdapter sınıfı ve bu sınıfın Fill() metodu hakkında yazılacak daha çok şey var. Yazılacak çok şey olsa bile bu sınıf hakkında ne söylenirse söylensin hiç birisi yeni şeyler olmayacaktı. Çünkü bu sınıfın bütün ayrıntıları hakkında bilgi MSDN’de bulunmaktadır. Buna rağmen birileri çıkıp Fill() metodunu kullanmayı ben akıl ettim derse gülmekten başka elimizden başka birşey gelmez.