Makale Özeti

Bu makalede ADO.NET 2.0 ile gelen bulk copy, batch update ve paging özellikleri ele alınmakatadır.

Makale

ADO .NET 2.0 İle Gelen Yeni Özellikler -5

 

Daha önceki aynı başlıklı ilk dört makalede, ADO.NET 2.0 ile yeni gelen şu özellikler ele alınmıştı :

  • M.A.R.S (Multiple Active ResultSets),
  • Dataset - DataReader entegrasyonu,
  • Dataset üzerinde gerçek anlamda binary serialization yapma imkanı,
  • Asenkron veri tabanı işlemleri,
  • Provider bağımsız kod'lama imkanı sağlayan DBProviderFactory sınıfı,
  • Tracing,
  • İstatiksel bilgi edinme,
  • Bağlantı havuzlama konusundaki eklentiler

Bu makalede ise ADO.NET 2.0’daki;  

 

  • Bulk Copy
  • Batch Update ve
  • Paging

 

konularına değinilmiştir.


Bulk Copy

 

Pek çok veri tabanı uygulaması, SQL Server’daki bir tabloya, -fazla miktarda kayıt içeren- veri yığınlarını, hızlı bir şekilde kopyalama ihtiyacı duyar. Bu işlem terminolojide bulk copy olarak bilinir. Söz konusu veriler herhangi bir kaynaktan elde edilmiş olabilirler. Örneğin bir dosyadan, başka bir veri tabanından ya da bilgisayar ile bağlantılı bir cihazın ürettiği sinyal çıktılarından. Bu noktada, SQL Server araç setinde bulunan bcp.exe isimli komut satırından çalışan uygulama, yukarıda anlatılan görevleri yerine getirmek üzere tasarlanmış bir araçtır.

 

NOT : Bu makalede amaç, bcp.exe ‘nin nasıl kullanılacağını anlatmak olmadığından, söz konusu uygulamanın kullanımına ilişkin detaylar irdelenmeyecektir !

 

ADO .NET 2.0 ‘daki SQLClient managed provider’ına eklenen, SqlBulkCopy sınıfı bcp.exe’nin yapabildiklerini, programatik olarak yapabilmeyi sağlar. Daha açık bir anlatımla, herhangi bir kaynaktan alınan veriler, bir DataSet’e, DataTable’a, bir DataRow dizisine veya DataReader’a alınabiliyorsa, SqlBulkCopy sınıfı kullanılarak, SQL Server’daki hedef tabloya, hızlı bir şekilde taşınabilirler. Ancak şu ayrıntıyı da unutmamak gerekir, SqlBulkCopy sınıfı verileri -bcp.exe ‘nin yapabildiği gibi- bir dosyadan okuyamaz.

 

İpucu : Bulk copy işlemi, insert deyimi kullanılarak yapılabilirse de, söz konusu sınıfın performansı çok daha iyidir.

 

SqlBulkCopy Sınıfının Üyeleri

 

Sınıfın başlangıç fonksiyonuna ait dört farklı versiyon bulunmakla birlikte, basit işlemler için üzerinde çalışacağı bağlantıyı temsil eden SqlConnection sınıfı türünde parametre alan versiyon kullanılabilir.

 

Ancak daha komplike işlemler için aşağıdaki versiyon da kullanılabilir :

 

SqlBulkCopy(SqlConnection, SqlBulkCopyOptions, SqlTransaction)

 

İkinci parametre kopyalama işlemi ile ilgili bir takım opsiyonların belirlendiği SqlBulkCopyOptions enum’ı türündeki bir değerdir. Bu parametreye;

 

  • SqlBulkCopyOptions.Default
  • SqlBulkCopyOptions.CheckContraints : Kopyalama işlemi sırasında default olarak kontrol edilmeyen kısıtlamaların, kontrol edilmesini sağlar.
  • SqlBulkCopyOptions.FireTriggers : Hedef tabloda tanımlanmış insert trigger’ı varsa tetiklenmesini sağlar.
  • SqlBulkCopyOptions.KeepIdentity : Kaynak verideki kimlik bilgilerinin (id’ler gibi) korunarak tabloya eklenmesini sağlar, aksi takdirde kimlik bilgileri hedef tabloda oluşturulur.
  • SqlBulkCopyOptions.KeepNulls : Hedef tablodaki null değerlerin mutlak korunumunu sağlar. Aksi durumda belirlenmiş default değerler, null değerlerin yerini alır.
  • SqlBulkCopyOptions.TableLock : Bulk copy sürecinde hedef tablonun tümüyle kilitlenmesini sağlar.
  • SqlBulkCopyOptions.UseInternalTransaction : Bulk copy işleminin her bir fazının içsel bir transaction’la yapılmasını sağlar. Ancak bu değerle birlikte üçüncü parametreye de bir SqlTransaction referansı geçilecek olursa exception oluşur.

 

değerleri geçilebilir. Üçüncü parametreye ise, manuel bir transaction’ı temsil eden SqlTransaction referansı geçilerek, kopyalama işleminin transactional davranması sağlanır.

 

WriteToServer() Metodu : Parametresine geçilen kaynak veriyi, DestinationTableName property’sinde belirlenen hedef tabloya kopyalar. Kaynak veri; DataSet, DataTable, DataRow dizisi veya DataReader olabilir.

 

DestinationTableName Property’si : Kopyalamanın yapılacağı hedef tablonun ismi.

 

NotifyAfter Property’si : Bu property’e atanacak olan integer değer, kaç kayıt kopyalandıktan sonra SqlRowsCopied event’inin raise edileceğini belirler.

 

SqlRowsCopied Event’i : NotifyAfter Property’sinde belirlenen sayıda kayıt kopyalandığında oluşur.

 

BatchSize Property’si : Bu property’e atanacak olan integer değer, kaç tane kaydın tek hamlede Sql Server’a gönderileceğini ifade eder.

 

Örnek : Aşağıdaki konsol uygulamasında, yeni_calisanlar.xml dosyasından GetNewEmployees() metodu ile alınan veriler, SqlBulkCopy ile Employees tablosuna aktarılmıştır.
 

public static DataTable GetNewEmployees()

{

        DataTable tbl = new DataTable();

        tbl.ReadXml(@"c:\yeni_calisanlar.xml");

        return tbl;

}

 

static void Main(string[] args)

{

        SqlBulkCopy bcp = new SqlBulkCopy("data source=.; database=Northwind; integrated security=true",
      SqlBulkCopyOptions.KeepIdentity);

 

        bcp.DestinationTableName = "Employees";

 

        bcp.WriteToServer(GetNewEmployees());

 

        bcp.Close();

} 

Batch Update (Toplu Güncelleme)

 

Bilindiği gibi ADO .NET ‘in önceki sürümlerinde, Dataset üzerinde yapılan değişiklikler DataAdapter sınıfının Update() metodu kullanılarak veri tabanına yansıtıldığında değişim geçiren her bir kayıt için veri tabanına gidilip gelinmesi gerekiyordu (round trips). Bu durum özellikle, -bu yolla güncellenen- fazla sayıda kayıt varsa, veri katmanı için kabul edilemez performans düşümlerine neden oluyordu.

 

ADO .NET 2.0 ‘da ise, SqlClient ve OracleClient managed provider’larındaki, DataAdapter sınıflarına eklenen UpdateBatchSize isimli property sayesinde söz konusu performans sorunu bertaraf edildi.

 

public override int UpdateBatchSize {get; set;}

 

UpdateBatchSize property’sine atanacak int türündeki değer; Dataset içerisinde değişime uğramış kaç tane kaydın, Update() fonksiyonu ile tek hamlede veri tabanına yansıtılacağını ifade eder. Sözgelimi, dataset içerisinde değişmiş 50 kayıt olduğunu farzedelim. Eski sürümlerde Update() çağrıldığı anda, veri katmanından veri tabanına 50 kez gidilip gelinecek (yani round trip oluşacak) ve özellikle network kaynaklı sebeplerle, belirgin bir yavaşlama kaçınılmaz olacaktı. Oysa yeni sürümde, bu property’e atanan değer 50 ise, değişmiş olan 50 kayıt tek hamlede “toplu olarak” veri tabanına yansıtılır ve işlem performansı artar.

 

Not : Bu property’e 1 değerinin atanması; batch update özelliğini devre dışı bırakacaktır.   

 


ADO .NET 2.0 ve Paging (Veri Sayafalama)

 

ADO .NET 2.0 Beta1 üzerinde yaptığımız incelemelerde, ilk planda paging konusunda yapılan bir eklenti dikkat çekiyordu. Söz konusu yenilik; Command sınıfına eklenen ExecutePageReader() isimli metottu. Bu metot sayesinde, veri tabanından alınan kayıt setinin, belirli bir index’ten başlayarak, n tane kaydı içeren bir sayfa biçiminde DataReader’a çekilmesi mümkün olabiliyordu. Ancak Beta2 ‘de bu fonksiyon maalesef varlığını koruyamadı.

 

Hatırlatma : Veri tabanından alınan büyük miktardaki verinin, görece daha küçük boyutlardaki alt kümelerine (sayfalara) bölünerek, işlenmesine paging denir.

 

Aykut TAŞDELEN

MVP (MS Most Valuable Professional)

aykut.tasdelen@yazgelistir.com