کانال بله, جهت پشتیبانی و اطلاع رسانی کانال بله, جهت پشتیبانی و اطلاع رسانی
عضویت

خواندن داده از SQL Server در سی شارپ (SqlDataReader)

پس از بررسی اصول اولیه کار با پایگاه داده، در این بخش از آموزش پایگاه داده در سی شارپ می خواهیم به روش کار با شی 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 را فراخوانی نمایید.

1395/10/09 25761 6016
رمز عبور : tahlildadeh.com یا www.tahlildadeh.com
نظرات شما

نظرات خود را ثبت کنید...