Makale Özeti

DataSet & DataTable sınıflarına ilişkin değişiklikler. Aykut TAŞDELEN

Makale

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)