مشخصات مقاله
-
6123
-
0.0
-
26129
-
0
-
0
خواندن داده از SQL Server در سی شارپ (SqlDataReader)
وقتی با پایگاه داده در C# کار میکنی، فقط اجرای دستورهای SQL و دریافت نتیجه مهم نیست؛ نحوه خواندن دادهها هم میتونه تأثیر زیادی روی عملکرد برنامه و مدیریت منابع داشته باشه. یکی از ابزارهای مهم برای این کار، SqlDataReader هست که برای خواندن سریع و ترتیبی دادهها از پایگاه داده استفاده میشه.
در این بخش از آموزش پایگاه داده در سی شارپ، با نحوه کار SqlDataReader، روش ایجاد اون و شیوه خواندن دادهها آشنا میشیم. اگر در حال یادگیری C# هستی، آشنایی با این شی و نحوه مدیریت درست اون، بخش مهمی از کار با دادهها در برنامههای سیشارپ محسوب میشه.
بعد از اینکه اصول اولیه کار با پایگاه داده رو بررسی کردیم، در این بخش از آموزش پایگاه داده در سی شارپ میخوایم با روش کار با شی SqlDataReader آشنا بشیم؛ شیای که بهطور اختصاصی برای خواندن دادهها از پایگاه داده استفاده میشه.
خواندن دادهها با استفاده از SqlDataReader
در این درس میخوایم نحوه خواندن دادهها با استفاده از شی SqlDataReader رو بررسی کنیم. اهداف کلی این درس شامل موارد زیر هستن:
- SqlDataReader در چه مواردی کاربرد داره؟
- دادهها چطور به وسیله شی SqlDataReader خوانده میشن؟
- چرا بستن SqlDataReader ضروریه؟
مقدمه
SqlDataReader نوعی شی هست که برای خواندن دادهها در شرایط مختلف و به شکل مؤثر کاربرد داره. با این شی به هیچ عنوان نمیتونید دادهای رو بنویسید. دادهها رو میشه به صورت متوالی و رو به جلو (forward only) از SqlDataReader خوند. هر بار که دادهای خونده میشه باید همون موقع اون رو در حافظه ذخیره کنید، چون بعد از خواندن یک داده، دیگه نمیتونید به عقب برگردید و دوباره اون رو بخونید.
طراحی forward-only در SqlDataReader یکی از دلایل اصلی سرعت بالای این شی هست. این شیء سربار اضافی مربوط به پیمایش یا بازنویسی دادهها در Data Source رو نداره. بنابراین، اگر دنبال یک روش سریع هستید و قراره مجموعهای از دادهها رو فقط یک بار بخونید، SqlDataReader انتخاب مناسبیه.
توجه داشته باشید که در پاراگراف قبلی، برای توضیح دلیل استفاده از SqlDataReader از عبارت «یک بار» استفاده کردیم. مثل هر بخش دیگهای از برنامه، اینجا هم ممکنه خطا (exception) اتفاق بیفته. در خیلی از موارد، استفاده از یک DataSet ذخیرهشده (Cached) میتونه گزینه مؤثری باشه.
ایجاد شی SqlDataReader
ایجاد یک نمونه از SqlDataReader کمی با روش نمونهسازی سایر شیهای ADO.NET فرق داره. برای این کار باید شی SqlDataReader رو تعریف کنید و خروجی متد ExecuteReader از نمونه شی SqlCommand رو به اون اختصاص بدید. مثال زیر رو ببینید:
SqlDataReader rdr = cmd.ExecuteReader();
متد ExecuteReader مربوط به شی SqlCommand (یا cmd)، یک نمونه از SqlDataReader رو برمیگردونه. البته ایجاد یک SqlDataReader بهتنهایی کاری برای شما انجام نمیده. همونطور که در درسهای قبلی یاد گرفتید، SqlDataReader برای دسترسی به دادهها به یک شی اتصال (SqlConnection)، یک شی برای اجرای دستور روی پایگاه داده (SqlCommand) و نتیجه حاصل از اجرای اون نیاز داره.
خواندن دادهها (Data Reading)
در درسهای قبلی، کدهایی داشتیم که از SqlDataReader استفاده میکردند، اما این مبحث رو بهصورت کامل بررسی نکردیم؛ بنابراین در این بخش میخوایم روی نکات و موضوعات خاص مربوط به اون تمرکز کنیم. این درس بر اساس مباحث قبلی پیش میره و نحوه استفاده از SqlDataReader رو از ابتدا توضیح نمیده. همونطور که قبلاً گفتیم، SqlDataReader دادهها رو از طریق جریانهای ترتیبی (Sequential Streams) در اختیار ما قرار میده. برای خواندن این دادهها باید اونها رو سطر به سطر از جدول دریافت کنید. وقتی یک سطر جدید خونده میشه، سطر قبلی دیگه در دسترس نخواهد بود. بنابراین، اگر بخواید اون سطر رو دوباره بخونید، باید یک نمونه جدید از SqlDataReader ایجاد کنید و دادهها رو دوباره از طریق جریان دادهای (Data Stream) بخونید.
روش رایج برای خواندن دادهها از جریان دادهای (Data Stream) که توسط SqlDataReader برگردونده میشه، اینه که دادههای هر سطر رو با یک حلقه while پردازش کنید. کد زیر نحوه انجام این کار رو نشون میده:
while (rdr.Read())
{
// get the results of each column
string contact = (string)rdr["ContactName"];
string company = (string)rdr["CompanyName"];
string city = (string)rdr["City"];
// print out the results
Console.Write("{0,-25}", contact);
Console.Write("{0,-20}", city);
Console.Write("{0,-25}", company);
Console.WriteLine();
}
در کد بالا به فرمان Read در SqlDataReader که داخل حلقه while قرار گرفته دقت کنید. مقدار بازگشتی Read از نوع داده بولی (bool) هست و تا زمانی که رکورد بیشتری برای خواندن وجود داشته باشه، شرط حلقه صحیح باقی میمونه. بعد از اینکه آخرین رکورد از جریان دادهای (Data Stream) خونده شد، شرط حلقه دیگه صحیح نخواهد بود و اجرای برنامه به خط بعد از حلقه منتقل میشه.
در درسهای گذشته، اولین ستون رو با استفاده از شاخص SqlDataReader یا rdr[0] از سطر استخراج (extract) کردیم. میتونید هر ستون از سطر رو با یک شاخص عددی مثل rdr[0] استخراج کنید، اما این روش چندان خوانا نیست. در مثال بالا از یک اندیس رشتهای (String Indexer) استفاده شده که نام ستون موجود در نتیجه Query رو مشخص میکنه. از اونجا که اندیسهای رشتهای خواناتر هستن، تغییر و نگهداری کد هم با استفاده از اونها راحتتر میشه.
صرفنظر از نوع پارامتر اندیس، یک اندیس SqlDataReader میتونه مقدار رو از نوع داده object برگردونه. به همین دلیل در مثال بالا نتایج رو به شکل یک رشته درمیاریم. هر بار که مقادیر استخراج میشن، میتونید هر کاری که لازم دارید با اونها انجام بدید؛ برای مثال، اونها رو روی کنسول چاپ کنید.
جمعبندی
همیشه یادتون باشه که بعد از تمام شدن کار با SqlDataReader، اون رو ببندید؛ درست مثل زمانی که SqlConnection رو میبندید. کد مربوط به دسترسی به دادهها رو داخل یک بلوک try قرار بدید و عملیات پایانی رو در بلوک finally، مثل نمونه زیر، انجام بدید:
try
{
// data access code
}
finally
{
// 3. close the reader
if (rdr != null)
{
rdr.Close();
}
// close the connection too
}
کد بالا ابتدا SqlDataReader رو بررسی میکنه تا مطمئن بشه این شی null یا پوچ نیست. وقتی برنامه مطمئن شد که یک نمونه مناسب از SqlDataReader وجود داره، میتونه اون رو ببنده. مثال زیر کد کامل مربوط به بخشهای قبلی رو نشون میده.
using System;
using System.Data;
using System.Data.SqlClient;
namespace Lesson04
{
class ReaderDemo
{
static void Main()
{
ReaderDemo rd = new ReaderDemo();
rd.SimpleRead();
}
public void SimpleRead()
{
// declare the SqlDataReader, which is used in
// both the try block and the finally block
SqlDataReader rdr = null;
// create a connection object
SqlConnection conn = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI");
// create a command object
SqlCommand cmd = new SqlCommand(
"select * from Customers", conn);
try
{
// open the connection
conn.Open();
// 1. get an instance of the SqlDataReader
rdr = cmd.ExecuteReader();
// print a set of column headers
Console.WriteLine("Contact Name City Company Name");
Console.WriteLine("------------ ------------ ------------");
// 2. print necessary columns of each record
while (rdr.Read())
{
// get the results of each column
string contact = (string)rdr["ContactName"];
string company = (string)rdr["CompanyName"];
string city = (string)rdr["City"];
// print out the results
Console.Write("{0,-25}", contact);
Console.Write("{0,-20}", city);
Console.Write("{0,-25}", company);
Console.WriteLine();
}
}
finally
{
// 3. close the reader
if (rdr != null)
{
rdr.Close();
}
// close the connection
if (conn != null)
{
conn.Close();
}
}
}
}
}
خلاصه
شی SqlDataReader این امکان رو فراهم میکنه که دادهها رو بهصورت سریع و رو به جلو (forward-only) بخونید. دادهها با خواندن هر سطر از جریان دادهای (Data Stream) در اختیار شما قرار میگیرن. برای جلوگیری از اتلاف منابع سیستم، بعد از تمام شدن کار حتماً فرمان Close رو برای SqlDataReader فراخوانی کنید.
اگر میخوای کار با C# و مباحث مرتبط با پایگاه داده رو اصولیتر یاد بگیری، میتونی مسیر یادگیریت رو با یک دوره جامع ادامه بدی. در دوره آموزش C# میتونی مباحث برنامهنویسی با سیشارپ رو در قالب یک مسیر آموزشی منسجم دنبال کنی و قدم بعدی یادگیریت رو برداری.