ADO.NET

Paylaş

.NET tabanlı programlama dilleri ile SQL Server, MySQL, Access, Oracle gibi veritabanı sistemleri arasında işlem yapmak için kullanılan ADO.NET ile ilgili bilgiler yer alıyor.

ADO.NET nedir?

ADO (ActiveX Data Objects) Microsoft firmasının veri kaynakları üzerinde işlem yapmasına imkan veren kütüphanesidir.

ADO.NET ise .NET platformunun çıkmasıyla birlikte ADO özelliklerinin geliştirilerek .NET platformuna dahil edilmiş halidir.

ADO.NET ile ADO arasındaki en büyük fark getirdiği Connected ve Disconnected çalışma özelliğidir.

Connected çalışma özelliği veriler üzerinde SQL ile anlık olarak işlem yapmasıdır.

Disconnected çalışma özelliği ise verilerin DataAdapter ile alınarak bellekte DataSet ve DataTable ile işlem yapılmasıdır.

Veri sağlayıcılar

ADO.NET yapısı sadece tek bir veritabanı sistemi ile değil belirlediği standart sayesinde ADO.NET için geliştirilmiş veri sağlayıcıları ile işlem yapmaya imkan verir.

.NET içerisinde varsayılan olarak SQL Server, OLE DB, ODBC ve Oracle veri sağlayıcıları ile gelmektedir.

MySQL, SQLite gibi farklı veritabanı sistemleri için geliştirilmiş veri sağlayıcılar eklenerek işlem yapılabilir.

ADO.NET sınıfları .NET platformunda System.Data alanında yer alır.

Veri sağlayıcıları ise genellikle System.Data.VeriSaglayici (System.Data.OleDb, System.Data.Odbc vb.) alanında yer alır.

.NET Core ile birlikte veri sağlayıcılar varsayılan olarak SDK ile gelmemektedir.

Veri sağlayıcılar aşağıdaki gibi Nuget paket yönetici kullanılarak projeye dahil edilir.

SQL Server veri sağlayıcısı için;

dotnet add package Microsoft.Data.SqlClient
# veya
Install-Package Microsoft.Data.SqlClient

SQLite veri sağlayıcısı için;

dotnet add package Microsoft.Data.Sqlite.Core
# veya
Install-Package Microsoft.Data.Sqlite.Core

MySQL ve MariaDB veri sağlayıcısı için;

dotnet add package MySql.Data
# veya
Install-Package MySql.Data

PostgreSQL veri sağlayıcısı için;

dotnet add package Npgsql
# veya
Install-Package Npgsql

Paket yöneticisi ve kullanımı için NuGet Nedir? ve .NET Core Kurulumu ve Kullanımı yazıma bakabilirsiniz.

NOT: Paket ile yüklenen veri sağlayıcılar veri sağlayıcısına göre Microsoft.Data.SqlClient, Npgsql, MySql.Data.MySqlClient alanı-namespace kullanır.

Veritabanı bağlantısı

ADO.NET içerisinde veritabanı bağlantısı kullanılan veri sağlayıcısına göre değişmektedir.

Örneğin; SQL SERVER için SqlConnection, SQLite için SqliteConnection sınıfları kullanılmaktadır.

Benzer şekilde komut (command), veri bağlayıcı (dataadapter) gibi yapılarda benzer isimle adlandırılmaktadır.

Bu sınıflar incelendiğinde DbConnection, DbCommand vb. sınıfların kullanıldığı görülür.

Zaten farklı veri sağlayıcısı kullanılsa da bağlantıyı açmak için Open metodunun kullanılma nedeni budur.

İşte bu standardı belirleyen ADO.NET içerisinde yer alan bu soyut sınıflardır.

Geliştirilen uygulamaların veri sağlayıcı bağımsız olması, uygulamanın daha sonra farklı veritabanı sistemine geçişinde kolaylık sağlayacaktır.

Örneğin; Küçük bir uygulama için Access veritabanı kullanıldığında OLE DB veya ODBC ön ekini kullanılması gerekir.

Uygulamanın daha sonra SQL Server veya Oracle gibi veritabanına geçişinde bağlantı sınıflarının düzenlenmesi gerekir.

Bu işlemlerin yapılması yerine ADO.NET 2.0 ile birlikte System.Data.Common alanında yer alan ve fabrika tasarım desenini kullanan DbProviderFactory sınıfı kullanılabilir.

Sınıf veritabanı işlemleri sırasında kullanılan soyut bağlantı (DbConnection), komut (DbCommand) sınıflarını dolaylı olarak oluşturan CreateConnection, CreateCommand gibi Create ile başlayan metotlara sahiptir.

DbProviderFactory sınıfı da soyut olduğundan dolayı bu sınıf DbProviderFactories sınıfında yer alan GetFactory metodu ile oluşturulur

DbProviderFactories sınıfında sistemde yüklü olan veri sağlayıcılarını listelemek için GetFactoryClasses metodu yer alır.

Metodun kullanımı aşağıdaki gibidir.

using System;
using System.Data;
using System.Data.Common;

class Program {

    static void Main() {

        DataTable VTBilgileri = DbProviderFactories.GetFactoryClasses();

        foreach (DataRow Satir in VTBilgileri.Rows) {
            foreach (DataColumn Sutun in VTBilgileri.Columns) {
                Console.WriteLine("{0, -30} : {1}", Sutun, Satir[Sutun]);
            }
            Console.WriteLine(new String('-', 30));
        }
    }
}

NOT: .NET Core ile birlikte veri sağlayıcılar ön tanımlı gelmediğinden veri sağlayıcısı tanımı yapılması gerekir.

Veri sağlayıcı tanımlama

Veri sağlayıcı tanımlamak için DbProviderFactories sınıfında yer alan RegisterFactory metodu kullanılır.

Metot parametre olarak veri sağlayıcıya ulaşmak için kullanılan takma adı – ve veri sağlayıcıya ait DbProviderFactory sınıfı örneğini alır.

SQL Server için;

DbProviderFactories.RegisterFactory("Microsoft.Data.SqlClient", Microsoft.Data.SqlClient.SqlClientFactory.Instance);

SQLite için;

DbProviderFactories.RegisterFactory("Microsoft.Data.Sqlite", Microsoft.Data.Sqlite.SqliteFactory.Instance);

MySQL ve MariaDB için;

DbProviderFactories.RegisterFactory("MySql.Data.MySqlClient", MySql.Data.MySqlClient.MySqlClientFactory.Instance);

PostgreSQL için;

DbProviderFactories.RegisterFactory("Npgsql", Npgsql.NpgsqlFactory.Instance);

NOT: Takma ad olarak veri sağlayıcı alanı-namespace kullanımı faydalı olacaktır.

DbProviderFactories sınıfında yer alan GetFactory metodu ise DbProviderFactory sınıfını oluşturmak için veri sağlayıcı takma adını, GetFactoryClasses metodu ile alınan herhangi bir DataRow nesnesini veya DbConnection nesnesini parametre olarak alan kullanıma sahiptir.

DbProviderFactory sınıfı kullanarak Access veritabanı bağlantısı aşağıdaki gibi sağlanabilir.

using System;
using System.Data;
using System.Data.Common;

class Program {

    static void Main() {

        DbProviderFactory Fabrika = DbProviderFactories.GetFactory("System.Data.OleDb");
        DbConnection Baglanti = Fabrika.CreateConnection();
        Baglanti.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=VT.mdb";

        Baglanti.Open();
        Console.WriteLine("Bağlantı durumu: {0}", Baglanti.State);
        Baglanti.Close();
    }
}

NOT: Access veritabanı bağlantısı için derleme işleminin 32 bit olarak (-platform:x86) yapılması gerekir.

Uygulamayı daha sonra MySQL veya SQL Server sistemine taşımak istediğimizde sadece System.Data.OleDb ve bağlantı cümlesini değiştirmemiz yeterli olacaktır.

Bağlantı cümlesi

ADO.NET ile veritabanı bağlantısı sırasında bağlantı cümlesi önemli bir yer tutar.

Bağlantı cümlesinin yanlış olması bağlantının sağlanamamasına sebep olur.

Ayrıca veri sağlayıcısına göre kullanılan bağlantı cümlesi farklılık gösterir.

Çeşitli veri sağlayıcıları için bağlantı cümlesi örnekleri connectionstrings.com adresinde yer almaktadır.

Ayrıca ADO.NET içerisinde yer alan DbConnectionStringBuilder sınıfı da kullanılabilir.

Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;
Data Source=MyOracleDB;Integrated Security=yes;
Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;

Yukarıda yer alan bağlantı cümleleri incelendiğinde her bir değerin noktalı virgül ile ayrıldığı görülür.

İşte DbConnectionStringBuilder sınıfı da benzer mantıkla içerisinde yer alan Add metodu sayesinde bu değerleri aşağıdaki gibi oluşturmamızı sağlar.

using System;
using System.Data;
using System.Data.Common;

class Program {

    static void Main() {

        DbProviderFactory Fabrika = DbProviderFactories.GetFactory("System.Data.OleDb");
        DbConnectionStringBuilder BaglantiCumlesi = Fabrika.CreateConnectionStringBuilder();
        BaglantiCumlesi.Add("Server", "myServerAddress");
        BaglantiCumlesi.Add("Database", "myDataBase");
        BaglantiCumlesi.Add("Uid", "myUsername");
        BaglantiCumlesi.Add("Pwd", "myPassword");

        Console.WriteLine("Bağlantı cümlesi : {0}",BaglantiCumlesi.ConnectionString);
    }
}

Örnekte de görüldüğü üzere bağlantı cümlesi daha anlaşılır bir şekilde oluşturulmuştur.

Veritabanı komutları

ADO.NET ile veri sağlayıcısına komut göndermek, çalıştırmak için DbCommand sınıfı ve metotları kullanılır.

Komutlar veritabanı sistemlerinde kullanılan SQL komutları olabileceği gibi Saklı yordam (stored prodecure) veya veri sağlayıcısına özel komutlar olabilir.

Komut bir işlem (insert, update, delete) ise ExecuteNonQuery, veri okuma (select) ise ExecuteReader sadece tek alan okuma ise ExecuteScalar metodu kullanılır.

Okuma işlemi sonucunda DbDataReader sınıfında yer alan metotlar ile ileri yönlü okuma yapılır.

using System;
using System.Data;
using System.Data.Common;

class Program {

    static void Main() {

        DbProviderFactory Fabrika = DbProviderFactories.GetFactory("System.Data.OleDb");
        DbConnection Baglanti = Fabrika.CreateConnection();
        Baglanti.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=VT.mdb";

        DbCommand Komut = Fabrika.CreateCommand();
        Komut.Connection = Baglanti;
        Komut.CommandType = CommandType.TableDirect;
        Komut.CommandText = "Uyeler";  // SELECT * FROM Uyeler

        Baglanti.Open();

        DbDataReader Okuyucu = Komut.ExecuteReader();

        while(Okuyucu.Read()) {
            Console.WriteLine("Sıra: {0}, Adı: {1}, Soyadı: {2}", Okuyucu[0], Okuyucu[1], Okuyucu[2]);
        }

        Baglanti.Close();
    }
}

NOT: TableDirect yöntemi SQL Server tarafından desteklenmemektedir.

Okuma işleminde tablo yapısı biliniyorsa DbDataReader sınıfında yer alan GetInt32, GetDouble, GetDateTime gibi metotlar kullanılırsa boxing-kutulama işlemi olmayacağı için daha performanslı olacaktır.

Saklım yordam kullanmak için CommandType değerinin StoredProcedure belirlenmesi yeterli olacaktır.

Veri ekleme, veri güncelleme veya veri silme işlemleri de benzer adımlar ile yapılır.

Güvenliğin önemli olduğu uygulamalarda DbParameter ile ön hazırlıklı sorguların kullanılması faydalı olacaktır.

using System;
using System.Data;
using System.Data.Common;

class Program {

    static void Main() {

        DbProviderFactory Fabrika = DbProviderFactories.GetFactory("System.Data.OleDb");
        DbConnection Baglanti = Fabrika.CreateConnection();
        Baglanti.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=VT.mdb";

        DbCommand Komut = Fabrika.CreateCommand();
        Komut.Connection = Baglanti;
        Komut.CommandText = "INSERT INTO Uyeler(Adı, Soyadı) VALUES(@Adı, @Soyadı)";

        Baglanti.Open();

        DbParameter Parametre1 = Fabrika.CreateParameter();
        Parametre1.ParameterName = "@Adı";
        Parametre1.Value = "Yusuf";
        Parametre1.DbType = DbType.String;
        Komut.Parameters.Add(Parametre1);

        DbParameter Parametre2 = Fabrika.CreateParameter();
        Parametre2.ParameterName = "@Soyadı";
        Parametre2.Value = "SEZER";
        Parametre2.DbType = DbType.String;
        Komut.Parameters.Add(Parametre2);

        string sonuc = Komut.ExecuteNonQuery() > 0 ? "Kayıt başarıyla eklendi." : "Hata oluştu.";
        Console.WriteLine(sonuc);

        Baglanti.Close();
    }
}

NOT: Komutları çalıştırmak için kullanılan ExecuteNonQuery metodu dönüş değeri olarak eklenen, güncellenen veya silinen kayıt sayısını verir.

Bağlantısız veritabanı işlemleri

Bağlantısız veritabanı işlemleri için DbDataAdapter, DataSet, DataTable, DataRow ve DataColumn gibi sınıflar kullanılır.

Bağlantısız veritabanı işlemlerinde veriler veritabanından DbDataAdapter ile alınarak bellekte DataSet veya DataTable içerisinde tutulur.

Yapılan değişikler DbDataAdapter sınıfında yer alan Update metodu çalıştırılmadıkça veritabanına yansımaz.

Bağlantısız veritabanı işlemleri ile çalışabilmek için DbDataAdapter sınıfındaki SelectCommand özelliğinin olması zorunludur.

using System;
using System.Data;
using System.Data.Common;

class Program {

    static void Main() {

        DbProviderFactory Fabrika = DbProviderFactories.GetFactory("System.Data.OleDb");
        DbConnection Baglanti = Fabrika.CreateConnection();
        Baglanti.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=VT.mdb";

        DbCommand Komut = Fabrika.CreateCommand();
        Komut.Connection = Baglanti;
        Komut.CommandText = "SELECT * FROM Uyeler";

        DbDataAdapter Baglayici = Fabrika.CreateDataAdapter();
        Baglayici.SelectCommand = Komut;

        DataTable Tablo = new DataTable();
        Baglayici.Fill(Tablo);

        foreach (DataRow Satir in Tablo.Rows) {
            Console.WriteLine("Sıra: {0}, Adı: {1}, Soyadı: {2}", Satir[0], Satir[1], Satir[2]);
        }
    }
}

Bağlantısız veritabanı üzerinde işlem yapmak için DataSet ve DataTable sınıfında yer alan metotlar kullanılır.

Yapılan ekleme, güncelleme ve silme işlemi için DbDataAdapter sınıfının InsertCommand, UpdateCommand, DeleteCommand özelliklerine uygun değerlerin yazılması gerekir.

Ancak her bir komutu yazmak zaman alacaktır.

Bunun yerine ADO.NET içerisinde yer alan DbCommandBuilder sınıfı da kullanılabilir.

using System;
using System.Data;
using System.Data.Common;

class Program {

    static void Main() {

        DbProviderFactory Fabrika = DbProviderFactories.GetFactory("System.Data.OleDb");
        DbConnection Baglanti = Fabrika.CreateConnection();
        Baglanti.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=VT.mdb";

        DbCommand Komut = Fabrika.CreateCommand();
        Komut.Connection = Baglanti;
        Komut.CommandText = "SELECT * FROM Uyeler";

        DbDataAdapter Baglayici = Fabrika.CreateDataAdapter();
        Baglayici.SelectCommand = Komut;

        DbCommandBuilder KomutOlusturucu = Fabrika.CreateCommandBuilder();
        KomutOlusturucu.DataAdapter = Baglayici;
        Baglayici.InsertCommand = KomutOlusturucu.GetInsertCommand();
        Baglayici.UpdateCommand = KomutOlusturucu.GetUpdateCommand();
        Baglayici.DeleteCommand = KomutOlusturucu.GetDeleteCommand();

        DataTable Tablo = new DataTable();
        Baglayici.Fill(Tablo);
        
        foreach (DataRow Satir in Tablo.Rows) {
            Console.WriteLine("Sıra: {0}, Adı: {1}, Soyadı: {2}", Satir[0], Satir[1], Satir[2]);
        }
    }
}

DbCommandBuilder sınıfı tablo yapısına uygun güvenli SQL komutlarını ekleme, güncelleme ve silme işlemleri için hazırlayacaktır.

Bağlantısız veritabanı işlemlerinde kayıt ekleme örneği aşağıda yer almaktadır.

using System;
using System.Data;
using System.Data.Common;

class Program {

    static void Main() {

        DbProviderFactory Fabrika = DbProviderFactories.GetFactory("System.Data.OleDb");
        DbConnection Baglanti = Fabrika.CreateConnection();
        Baglanti.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=VT.mdb";

        DbCommand Komut = Fabrika.CreateCommand();
        Komut.Connection = Baglanti;
        Komut.CommandText = "SELECT * FROM Uyeler";

        DbDataAdapter Baglayici = Fabrika.CreateDataAdapter();
        Baglayici.SelectCommand = Komut;

        DbCommandBuilder KomutOlusturucu = Fabrika.CreateCommandBuilder();
        KomutOlusturucu.DataAdapter = Baglayici;
        Baglayici.InsertCommand = KomutOlusturucu.GetInsertCommand();
        Baglayici.UpdateCommand = KomutOlusturucu.GetUpdateCommand();
        Baglayici.DeleteCommand = KomutOlusturucu.GetDeleteCommand();

        DataTable Tablo = new DataTable();
        Baglayici.Fill(Tablo);
        
        DataRow YeniKayit = Tablo.NewRow();
        YeniKayit[1] = "Yusuf";
        YeniKayit[2] = "SEZER";
        Tablo.Rows.Add(YeniKayit);

        int KayitSayisi = Baglayici.Update(Tablo);        
        Console.WriteLine("Etkilenen Kayıt Sayısı: {0}", KayitSayisi);
    }
}

Bağlantısız veritabanı işlemleri küçük boyutlu veriler ile işlem yaparken faydalı olurken büyük boyutlu verilerde performansı azaltmaktadır.

Ayrıca bağlantısız veritabanı işlemlerinde tablolar arası ilişkilerin DataRelation ile belirlenmesi gerekir.

Bağlantısız veritabanı işlemlerinde veriler anlık olarak veritabanına yansıtılmadığından aynı veriler üzerinde işlem yapan uygulamalarda çeşitli çakışmalara neden olacaktır.

Son

Veritabanı işlemleri sırasında daha esnek bir yapı sunduğundan LINQ to SQL, ORM (Entity Framework, Dapper, NHibernate) gibi yapıların kullanımı faydalı olacaktır.

C# ve ADO.NET kullanarak yaptığım örneğe buradan ulaşabilirsiniz.

.NET Derslerine buradan ulaşabilirsiniz.

Hayırlı günler dilerim.


Bunlarda ilgini çekebilir


LinkedIn grubuna buradan katılın.