SqlDataReader Sınıfını Daha Etkili Kullanalım
SqlDataReader sınıfı verileri listelemek veritabanından sorgulamak için kullanılan “Connected” bağlantılı bir sınıftır. SqlDataReader okuma görevini yerine getirirken sürekli bir Sql sunucu bağlantısına ihtiyaç duyar ve network trafiğini meşgul eder, aynı zamanda kullandığı SqlConnection nesnesinin başka işlemler için kullanılmasını engeller. Bu sebepten dolayı SqlDataReader sadece okuma,listeleme ve yalnızca okunabilir veriler için kullanılması önerilir. Avantajı ise ileri yönlü okuma işlemi gerçekleştirdiği için DataAdapter sınıfına göre daha hızlı çalışır.
Veri tabanı ile ilgili işlemlerde geliştirme yapan bir yazılımcı mutlaka DataReader ve DataAdapter gibi nesneleri kullanmıştır. Şimdi SqlDataReader nesnesini daha etkili kullanabilmek için yararlı özelliklerine göz atalım. SqlCommand nesnesini SqlDataReader ile verilerini okumak için ExecuteReader() metodunu kullanıyoruz. ExecuteReader metoduna değişik parametreler vererek performansını daha da arttırabiliriz. SqlCommand nesnesinin ExecuteReader metodunun alabileceği CommandBehavior değerleri aşağıdaki gibidir;
- CommandBehavior.CloseConnection: SqlDataReader nesnesi işlemi bittikten sonra otomatik olarak kapatılır. Eğer kullanmaz isek ve kendimiz kod blogunun sonunda Connection’nu kapatmaz isek hata meydana gelecektir.
- CommandBehavior.SingleRow: En çok kullanılan parametrelerden birisidir. Eğer sorgu sonucu tek bir kayıt döndürecek ise bu değeri kullanmalıyız. Sorgu performansını olumlu yönde etkiler. Örn: ID değeri 11 olan müşteri bilgisi gibi.
- CommandBehavior.SingleResult: Tek bir değer döndürecek sorgularda kullanılır. Bir tablodaki kayıt sayısı,haftalık satış gibisi gibi. Tek bir değer döndüren sorgularda tercil edilmelidir.
- CommandBehavior.SequentialAccess: Çok büyük boyutlu binary tipte veriler için kullanılabilir.
- CommandBehavior.KeyInfo: Tabloya ait anahtan alan bilgilerini çekerken kullanabiliriz.
Şimdi sırası ile ilgili davranışları inceleyeceğimiz basit bir Console Application uygulaması yapalım. Ben çalışmamda Adventurework veri tabanını kullanacağım.
CommandBehavior.CloseConnection Örneği:
[csharp]
string db = "Data Source=.;Initial Catalog=AdventureWorks2012;User Id=sa;Password=1";
SqlConnection con = new SqlConnection(db);
SqlCommand cmd = new SqlCommand("select TOP 10 ProductNumber,Name,ListPrice from Production.Product", con);
con.Open();
Console.WriteLine("Bağlantı Durumu: " + con.State.ToString());
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
Console.WriteLine("———————————————");
while (dr.Read())
{
Console.WriteLine(string.Format("Ürün Kodu= {0} – Ürün Adı= {1} – Fiyatı={2}", dr["ProductNumber"].ToString(), dr["Name"].ToString().Substring(0, 15), dr["ListPrice"].ToString()));
}
dr.Dispose();
Console.WriteLine("———————————————");
Console.WriteLine("İşlem sonunda bağlantı durumu: " + con.State.ToString());
Console.ReadKey();
[/csharp]
ConnectionState bağlantımızın o anki durumunu bize döndürür. Kodlarımızın başında açmış olduğumuz bağlantıyı kendimiz kapatmadan CommandBehavior.CloseConnection sayesinde otomatik olarak işi bitince kapatmaktadır.
CommandBehavior.SingleRow Örneği:
[csharp]
string db = "Data Source=.;Initial Catalog=AdventureWorks2012;User Id=sa;Password=1";
SqlConnection con = new SqlConnection(db);
SqlCommand cmd = new SqlCommand("select AVG(ListPrice) as ORT from Production.Product", con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SingleRow);
Console.WriteLine("———————————————");
while (dr.Read())
{
Console.WriteLine(string.Format("Ortalama Ürün Adet Fiyatı= {0} ", dr["ORT"].ToString()));
} dr.Dispose(); con.Close();
Console.WriteLine("———————————————");
Console.ReadKey();
[/csharp]
Bu sefer production.product tablomda bulunan ürünlerin ortalama fiyatını sistemden çekiyorum. Tek kayıt dönen sorgularda SingleRow kullanmak fazladan performans sağlayacaktır.
CommandBehavior.SchemaOnly Örneği:
[csharp]
string db = "Data Source=.;Initial Catalog=AdventureWorks2012;User Id=sa;Password=1";
SqlConnection con = new SqlConnection(db);
SqlCommand cmd = new SqlCommand("select * from Production.Product", con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SchemaOnly);
Console.WriteLine("———————————————");
dr.Read();
for (int i = 0; i<dr.FieldCount; i++)
{ Console.WriteLine(dr.GetName(i)+" = "+dr.GetFieldType(i));
}
dr.Dispose();
con.Close();
Console.WriteLine("———————————————");
Console.ReadKey();
[/csharp]
SchemaOnly sorgu ne olursa olsun sadece alan bilgilerini döndürür. Herhangi bir veri döndürmez.
CommandBehavior.SequentialAccess Örneği:
Bu sefer Production.Product tablomda bulunan ürün adını GetChars metodunu kullanarak alan içerisindeki veriyi karakter karakter okuyor ve belleğe yüklüyorum. GetChars metodu 5 parametre almaktadır. İlk parametre hangi alanın okunacağını belirtir,ikinci parametre kaçıncı karakterden itibaren okunacağı,üçüncü parametre char türünden bir diziyi belirtir,dördüncü parametre dizinin kaçıncı elemanından itibaren aktarımın yapılacağını belirtir. Son parametre ise ne kadar karakter okunacağını belirtir.
[csharp]
string db = "Data Source=.;Initial Catalog=AdventureWorks2012;User Id=sa;Password=1";
SqlConnection con = new SqlConnection(db);
SqlCommand cmd = new SqlCommand("select Name from Production.Product", con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
Console.WriteLine("———————————————");
dr.Read(); char[] ch = new char[40]; dr.GetChars(0, 0, ch, 0, 40);
//Alanımızı char olarak dizimize aktarıyoruz.
foreach (var item in ch) { Console.Write(item); }
dr.Dispose();
con.Close();
Console.WriteLine();
Console.WriteLine("———————————————");
Console.ReadKey();
[/csharp]
CommandBehavior.KeyInfo Örneği:
[csharp]
string db = "Data Source=.;Initial Catalog=AdventureWorks2012;User Id=sa;Password=1";
SqlConnection con = new SqlConnection(db);
SqlCommand cmd = new SqlCommand("select * from Production.Product", con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
Console.WriteLine("———————————————");
DataTable dt = dr.GetSchemaTable();
foreach (DataRow item in dt.Rows)
{
var name = item["ColumnName"];
var type = item["DataTypeName"];
Console.WriteLine("{0} {1}",name,type);
}
dr.Dispose();
con.Close();
Console.WriteLine();
Console.WriteLine("———————————————");
Console.ReadKey();
[/csharp]
Faydalı olması dileğiyle…
merhaba,
c# da oluşturduğum sql veritabanlı programıma kayıt eklerken
id numarasının gözükmesini istiyorum yani ben bilgileri kaydetmeden önce son
id nin bir fazlası formda gözüksün böylece kayıt gerçekleşince kayıt sırasında gözüken id ile
kayıt bittikten sonra gözüken id eşit olsun. mümkün mü acaba?
Merhaba, Oracle da ExecuteReader() metodunu çalıştırdığımda içerideki string yazılardaki ı harfleri i harfi oluyor ne yapmalıyım?