کلاس DataReader

کلاس dataReader امکان دسترسی به دیتابیس را به ما می‌دهد. این دسترسی فقط برای دیدن اطلاعات است و نمی‌توان اطلاعات را تغییر داد (read-only). استفاده از این کلاس یک روش متصل (connected) است، یعنی آفلاین نمی‌توان از آن استفاده کرد و همیشه یک connection باز برای ما لازم است. هر data provider، کلاس dataReader مربوط به خودش را دارد که همه آنها از کلاس پایه system.data.common.DbDatareader ارث بری می‌کنند.

DataReader Class provider
SqlDataReader SQL Server
OleDbDataReader OLE DB
OdbcDataReader ODBC

کلاس DbDataReader شامل متدها و خاصیت‌هایی برای خواندن از دیتابیس هستند. تعدادی از آن‌ها را در جدول‌های زیر آورده‌ام.

خاصیت توضیحات
FieldCount تعداد ستون‌های ردیف (فعلی) را به ما می‌گوید.
HasRows به ما می‌گوید که این query حداقل یک ردیف دارد یا نه؟
IsClosed مشخص می‌کند که Dbdatareader بسته است یا نه؟
RecordsAffected تعداد ستون‌هایی که با اجرای دستور SQL تغییر یافته‌اند را بر می‌گرداند (ستون‌هایی که update ،insert یا delete شده‌اند).

 

متد توضیحات
GetBoolean مقدار یک ستون را به صورت Boolean بر می‌گرداند.
GetChar مقدار یک ستون را به صورت char برمی گرداند.
GetDataTypeName اسم dataType (نوع داده) ستون فعلی را برمی گرداند.
GetDateTime مقدار ستون را به عنوان dateTime (شیئی که تاریخ و زمان را می‌دهد) برمی گرداند.
GetDecimal مقدار دهدهی ستون را برمی گرداند.
GetDouble مقدار اعشار ستون را بر می‌گرداند.
GetFieldType نوع فیلد ستون مورد نظر را بر می‌گرداند.
GetInt32 مقدار ستون مورد نظر را به عنوان interger برمی گرداند.
GetName اسم ستون را بر می‌گرداند.
GetString مقدار ستون را به صورت string می‌دهد.
GetValue مقدار ستون را به صورت یک شیء برمی گرداند.
GetValues تمام ستون‌های یک ردیف را به صورت آرایه‌ای از اشیاء بر می‌گرداند.
NextResult وقتی در حال خواندن دسته‌ای از نتایج هستیم این متد به ما نتیجه بعدی را می‌دهد.
Read Reader (برای خواندن استفاده می‌شود) را به رکورد بعدی می‌برد.

dataReader با هر بار خواندن تنها یک رکورد را به حافظه می‌آورد. این کار برای استفاده بهینه از حافظه مفید است. Datareader احتیاج دارد که connection باز باشد پس برای استفاده از آن باید کانکشن را اول باز کرد و به محض اتمام کار آن را بست. برای یک دستور SELECT باید از متد ()ExecuteReader استفاده کنیم تا به ما یک شیء DbDataReader برگرداند.

SqlCommand command = new SqlCommand("SELECT * FROM Students", connection);
SqlDataReader reader;

connection.Open();
reader = command.ExecuteReader();

می‌بینیم قبل از این که از ExecuteScalar استفاده کنیم باید کانکشن را باز کنیم. ما این کار را با استفاده از تابع DbConnection.Open انجام می‌دهیم. ورژن دیگر ExecuteScalar پارامتر می‌گیرد (overloader constructor) که مجموعه این پارامترها را می‌توانیم در نوع شمارشی System.Data.CommandBehavior ببینیم. در جدول زیر یک سری از این مقادیر را می‌بینیم.

مقدار توضیحات
CloseConnection وقتی متد close از dataReader صدا زده می‌شود، بلافاصله کانکشن را می‌بندد.
Default رفتار پیشفرض DataReader را مشخص می‌کند.
SingleResult پرس و جو، یک مقدار واحد بر می‌گرداند.
SingleRow انتظار می‌رود که پرس و جو یک سطر ساده را برگرداند.

به عنوان مثال وقتی شما می‌خواهید که فقط یک ردیف خوانده شود باید SingleRow را به عنوان پارامتر به آن ارسال کنید مانند کد زیر:

reader = command.ExecuteReader(CommandBehavior.SingleRow);

با استفاده از OR بیتی می‌توانیم این رفتارها را با هم ترکیب کنیم.

reader = command.ExecuteReader(CommandBehavior.SingleRow | CommandBehavior.CloseConnection);

وقتی که ExecuteReader اجرا شد و یک نمونه (Instance) از DbDataReader را برای ما برگرداند آن را در یک متغیر قرار می‌دهیم. حال با استفاده از حلقه در میان نتایجی که به وسیله دستور SELECT برگردانده شده‌اند حرکت کنیم. به کد زیر توجه کنید :

while (reader.Read())
{
   MessageBox.Show(reader["FirstName"].ToString());
}

در قسمت شرط حلقه ما متد ()read را از DataReader فراخوانی کرده‌ایم که ردیف اول را که از پرس و جو به دست آمده است به ما بر می‌گرداند. اگر عملیات خواندن یک رکورد (سطر) موفقیت آمیز باشد در این صورت true را برمی گرداند و در نتیجه حلقه ادامه پیدا می‌کند در غیر این صورت false برمی گرداند و از حلقه خارج می‌شود. وقتی که به صورت موفقیت آمیز یک ردیف را برگردانید حالا می‌توانیم با استفاده از نام ستون مقدار یک خانه از جدول را استفاده کنیم همانطور که در کد بالا آن را چاپ می‌کند. بعد از این که بلاک تمام شد دوباره شرط حلقه اجرا می‌شود پس متد ()Read بار دیگر اجرا می‌شود و این بار ردیف بعدی را برمی گرداند. به جای این روش ما می‌توانیم از متد ()Get مربوط به DataReader استفاده کنیم، که ایندکس مربوط به ستونی که می‌خواهیم بخوانیم را دریافت می‌کند. به عنوان مثال برای برگرداندن مقدار ستون اول از کد زیر استفاده می‌کنیم:

int studentID = reader.GetInt32(0);

همانطور که مشاهده می‌کنید مقدار ستون اول (اندیس 0) به عنوان یک عدد صحیح برگشت داده می‌شود. بعد از استفاده کردن از DataReader باید آن و همچنین connection را بست تا بی خود از منابع استفاده نکند.

reader.Close();
connection.Close();

در درس بعد ما از کلاس‌های DateReader برای محتویات داخل یک دیتابیس در حالت متصل صحبت می‌کنیم.