DataSet و يا DataReader ؟

DataReader و DataSet دو شی ارائه شده در ADO.NET به منظور دستيابی به داده می باشند . اشياء فوق امکانات متعددی برای دستيابی به داده در برنامه های دات نت را در اختيار پياده کنندگان قرار می دهند . Scott Mitchell...
پنجشنبه، 3 بهمن 1387
تخمین زمان مطالعه:
موارد بیشتر برای شما
DataSet و يا DataReader ؟
DataSet و  يا DataReader ؟
DataSet و يا DataReader ؟

DataReader و DataSet دو شی ارائه شده در ADO.NET به منظور دستيابی به داده می باشند . اشياء فوق امکانات متعددی برای دستيابی به داده در برنامه های دات نت را در اختيار پياده کنندگان قرار می دهند . Scott Mitchell اخيرا" در مقاله ای جامع که بر روی سايت http://www.4guysfromrolla.com منشتر شده است به بررسی دو شی فوق پرداخته و آنان را از زوايای متفاوتی مقايسه و در نهايت به اين نتيجه رسيده است که استفاده از DataReader در برنامه های وب دارای مزايای بمراتب بيشتری نسبت به DataSet است . برای آشنائی با دلايل وی برای رسيدن به نتيجه فوق ، خلاصه ای از مقاله وی را در ادامه با هم مطالعه می کنيم .

مبانی و اصول اوليه DataReader

DataReader و DataSet دارای وظايف متفاوتی بوده و با اهداف مختلفی طراحی و پياده سازی شده اند :
• DataSet : يک بانک اطلاعاتی کوچک در حافظه
• DataReader : ترابری داده بين لايه بانک اطلاعاتی و يک برنامه دات نت
در ADO.NET يک provider شامل تعدادی منبع است و کلاس های خاص مرتبط با هر provider به منظور کار با ارائه دهندگان مربوطه ارائه شده است . مثلا" کلاس های SqlConnection, SqlCommand, SqlDataAdapter و SqlDataReader جهت کار با SqlClient provider و کلاس های OleDbConnection, OleDbCommand, OleDbDataAdapterو OleDbDataReader جهت کار با OleDb provider ارائه شده اند.اشيائی که شامل يک پيشوند با نام يک provider می باشند ( نظير Sql,OleDb,Oracle و ... ) ، اشياء مختص و وابسته به Provider بوده و به منظور کار با يک Provider خاص طراحی و پياده سازی شده اند.
DataReader يکی از اشياء فوق است ( SqlDataReader, OleDbDataReader ) .به منظور استفاده از شی فوق می بايست در ابتدا يک connection به منبع داده ايجاد و query مورد نظر جهت اجراء مشخص گردد . در ادامه DataReader ايجاد و به عنوان يک پل ارتباطی بين برنامه دات نت و منبع ذخيره سازی داده ايفای وظيفه می نمايد . مثلا" می توان از کد زير در اين رابطه استفاده نمود :

 ' Create command
Dim myCommand as New SqlCommand(myConnection, SQL query or stored procedure)

' Create a DataReader to ferry information back from the database
Dim myReader as SqlDataReader
myReader = myCommand.ExecuteReader()

'Iterate through the results
While myReader.Read()
'... Work with the current record ...
End While

' Close the connection (will automatically close the reader)
myConnection.Close()


DataReader در هر لحظه يک رکورد را از منبع ذخيره سازی داده load می نمايد . هر مرتبه که متد Read شی DataReader فراخوانده گردد ، DataReader رکورد جاری را کنارگذاشته و با مراجعه به بانک اطلاعاتی ، رکورد بعدی را بازيابی می نمايد .در صورتی که يک سطر از بانک اطلاعاتی load شده باشد ، متد Read مقدار True و اگر رکوردی برگردانده نشود ، مقدار False برگردانده خواهد شد .
DataReader ، يک شی داده Connected بوده و نيازمند وجود يک اتصال فعال با بانک اطلاعاتی است . بخاطر داشته باشيد که DataReader صرفا" مکاينزم لازم برای ترابری داده بين برنامه و بانک اطلاعاتی را ارائه نموده و پس از قطع connection ، امکان برگرداندن اطلاعات به بانک اطلاعاتی وجود نخواهد داشت . DataReader دارای ويژگی فقط خواندنی و فقط به سمت جلو می باشد . اين بدان معنی است که اطلاعات بازيابی شده از بانک اطلاعاتی را نمی توان با استفاده از DataReader تغيير و يا اقدام به بازيابی رکوردها به صورت تصادفی نمود . DataReader محدود به دستيابی رکوردها به صورت ترتيبی ( از اولين رکورد به سمت آخرين رکورد ) است .

مبانی و اصول اوليه DataSet

DataSet يک شی بمراتب پيچيده تر و با ويژگی های بيشتر در مقايسه با DataReader است . در حالی که DataReader به سادگی عمليات برگرداندن داده از يک منبع داده را برعهده دارد ، DataSet را می توان به منزله يک بانک اطلاعاتی مقيم در حافظه تصور نمود . DataSet همانند يک بانک اطلاعاتی از مجموعه ای جدول تشکيل شده است . يک DataSet از مجموعه ای شی DataTable تشکيل می گردد . همانگونه که يک بانک اطلاعاتی می تواند دارای ارتباطاتی بين جداول مربوطه به خود باشد ( به همراه محدوديت های متفاوتی در ارتباط با فيلدهای تعريف شده در هر يک از جداول ) ، يک DataSet نيز می تواند دارای ارتباطات مشخص بين اشياء DataTable مربوط به خود و محدوديت های لازم برروی فيلدهای DataTable باشد .
برخلاف DataReader ، يک DataSet يک شی داده مستقل از Provider است و در اين رابطه اشيائی نظير SqlDataSet و يا OleDbDataSet وجود ندارد و اين مسئوليت شی DataAdapter مربوط به Provider است که داده مختص provider را درون يک DataSet مستقل ( نه يک provider خاص ) ترجمه نمايد . کد زير نحوه استفاده از DataSet را نشان می دهد :

 '  Establish Connection
Dim myConnection as New SqlConnection(connection string)
myConnection.Open()

' Create command
Dim myCommand as New SqlCommand(SQL query or stored procedure, myConnection)

' Create the DataAdapter
Dim myDataAdapter as New SqlDataAdapter(myCommand)

' Create the DataSet
Dim myDataSet as New DataSet

' Fill the DataSet
myDataAdapter.Fill(myDataSet)

' Close the connection
myConnection.Close()

'... Work with the contents of the DataSet ...


همانگونه که در کد فوق مشاهده می گردد ، متد Fill مربوط به شی DataAdapter مسئوليت پر نمودن DataSet را با توجه به query مورد نظر برعهده دارد . در پس پرده ، از يک DataReader به منظور خواندن نتايج اجرای query و پر نمودن DataSet استفاده می گردد. DataSet يک شی داده disconnected است. اين بدان معنی است که پس از استقرار داده در DataSet ، می توان connection را غيرفعال ( close ) و همچنان بررسی و پردازش لازم بر روی داده های موجود در DataSet را انجام داد .
با توجه به اين که DataSet يک مجموعه از داده های غيرمتصل جداگانه را ارائه می نمايد ، امکان ويرايش و دستيابی تصادفی به اطلاعات موجود در آن وجود خواهد داشت . دو ويژگی فوق در DataReader وجود ندارند . علاوه بر موارد فوق ، DataSet دارای پتانسيل های قدرتمندی به منظور کار با اسناد XML است . مثلا" می توان با استفاده از متد WriteXml اطلاعات موجود در يک DataSet را درون يک فايل XML مستقر و يا می توان اطلاعات موجود در يک فايل XML را با استفاده از متد ReadXml شی DataSet خواند و در يک DataSet مستقر نمود .

DataReader و يا DataSet

صرفنظر از اين که از DataSet و يا DataReader به منظور بازيابی داده های موجود در بانک اطلاعاتی استفاده می گردد ، می توان به منظور نمايش داده های مورد نظر از کنترل های DataList, DataGrid و يا Repeater با استفاده از يک کد مشابه استفاده نمود . بدين منظور لازم است که خصلت DataSource هر يک از کنترل های فوق به DataReader و يا DataSet نسبت داده شده و در ادامه متد DataBind مربوطه ( کنترل های DataList, DataGrid و يا Repeater ) فراخوانده گردد .
کار با داده ها در ASP.NET بسيار ساده است بگونه ای که معمولا" پياده کنندگان برنامه های وب ASP.NET هرگز اين موضوع را به ذهن خود خطور نخواهند داد که بهترين شی که می توان از آن به منظور دستيابی به داده استفاده نمود ، چيست ؟ آنان بر اين عقيده هستند که همه چيز معادل هم بوده و خيلی مهم نخواهد بود که از کدام شی در اين رابطه استفاده می گردد .
آيا واقعا" همه چيز يکسان و معادل می باشد ؟ به وضوح مشخص است که بين ويژگی ها و پتانسيل های ارائه شده توسط هر يک از اشياء DataReader و DataSet تفاوت های عمده ای وجود دارد . DataSet ويژگی های بمراتب بيشتری را در اختيار پياده کنندگان قرار می دهد و همين موضوع باعث شده است که کارآئی آن برای خواندن داده نسبت به DataReader کمتر گردد .
بر اساس مطالعه انجام شده در رابطه با سرعت بازيابی داده در ADO.NET ، سرعت و کارآئی DataReader سی مرتبه بيش از DataSet می باشد . در بررسی انجام شده بر روی يکهزار رکورد بازيابی شده ، مشخص شده است که DataSet سی مرتبه کندتر از DataReader است ( 89 / 8 ثانيه در مقابل 29 /0 ثانيه ) .

موارد استفاده مفيد از DataSet

صرفنظر از محدوديت های DataSet از بعد کارآئی ، در مواردی لازم است که از اين شی استفاده گردد و گرنه شی فوق به عنوان يکی از عناصر کليدی در فريمورک دات نت محسوب نمی گرديد . استفاده از DataSet در يکی از دو مورد زير می تواند مفيد واقع شود :
• برنامه های Desktop : فرض کنيد دارای يک برنامه ورود اطلاعات desktop-based باشيم . يک کاربر برنامه را اجراء ، داده هائی خاص را از برخی بانک های اطلاعاتی load و پس از اعمال تغييرات لازم آنان را در بانک اطلاعاتی ذخيره می نمايد . وضعيت فوق يک حالت ايده آل برای DataSet است و امکان خواندن داده ها از درون يک DataSet مستقر در حافظه کامپيوتر سرويس گيرنده ، وجود خواهد داشت . بدين ترتيب کاربران می توانند با داده ها بدون نياز به ارتباط مستمر با بانک اطلاعاتی کار کنند . پس از اتمام عمليات ويرايش داده ها ، به منظور اعمال تغييرات لازم می توان از يک Batch update استفاده نمود . از آنجائيکه DataSet يک منبع ذخيره سازی داده disconnected است ، امکان دستيابی offline به داده ها وجود خواهد داشت .
چنين وضعيتی ممکن است در يک برنامه وب نيز محقق گردد و لازم باشد که کاربران با برنامه وب همانند آنچه اشاره گرديد ، ارتباط برقرار نمايند . آنان يک صفحه وب را مشاهده نموده و پس از اعمال تغييرات لازم ، صرفا" با فعال نمودن يک دکمه Update تغييرات را در بانک اطلاعاتی ثبت نمايند .بانک اطلاعاتی مورد نظر بهنگام نمی گردد تا زمانی که دکمه Update فعال گردد . در چنين مواردی می توان از يک Dataset مبتنی بر Session استفاده نمود.
• ارسال و يا دريافت از راه دور اطلاعات از بانک اطلاعاتی به منظور برقراری ارتباط بين پلت فورم های متفاوت : با توجه به اين موضوع که يک DataSet می تواند به سادگی درون يک فايل XML قرار داده شود و يا از آن خوانده شوند ، به عنوان اولين کانديد برای ارسال اطلاعات بين پلت فورم های متفاوت مطرح می باشد .مثلا" در صورتی که قصد برگرداندن داده بانک اطلاعاتی را از طريق يک سرويس وب داشته باشيد ، يکی از روش های موجود در اين زمينه اين است که داده های بانک اطلاعاتی درون يک DataSet قرار داده شوند و در ادامه با استفاده از متد سرويس وب، DataSet برگردانده شود . در چنين حالتی DataSet به صورت اتوماتيک درون يک فايل XML قرار داده شده و ارسال می گردد .

علل استفاده از DataSet و علل عدم استفاده از DataSet

در برنامه های وب به مواردی برخورد می کنيم که شايد استفاده از DataSet تنها گزينه موجود در اين رابطه باشد . مثلا" فرض کنيد قصد داريم برخی اطلاعات موجود در بانک اطلاعاتی را Cache نموده تا از آنان در صفحات متعددی بر روی يک سايت استفاده گردد . اين نوع داده ها ممکن است وابسته به نوع کاربر بوده و در Session ذخيره شده باشند و يا ممکن است توسط تمامی کاربران استفاده گردند . در چنين مواردی می بايست اطلاعات را در Data Cache ذخيره نمود .
DataReader با توجه به اين که يک شی disconnected است ، نمی تواند برای Cache کردن داده ها مورد استفاده قرار گيرد و در زمان استفاده از آن می بايست اتصالات به بانک اطلاعاتی فعال و بسيار کوتاه باشند ( Short-Live ) . با توجه به موارد فوق در صورتی که قصد داريد داده های بانک های اطلاعاتی را Cache نمائيد ، استفاده از DataSet می تواند يکی از گزينه های موجود در اين رابطه باشد .ولی آيا اين تنها گزينه موجود است ؟ در چنين مواردی می توان يک کلاس را ايجاد که دارای خصلت هائی متناظر و مرتبط با فيلدهای بانک اطلاعاتی است که قصد ذخيره آنان در يک DataSet را داريد . در زمان Cache نمودن داده می توان از يک DataReader به منظور خواندن query از بانک اطلاعاتی ، بازيابی و حرکت بين رکوردهای برگردانده شده استفاده نمود . در اين رابطه لازم است برای هر رکورد يک نمونه کلاس سفارشی شده ايجاد ، خصلت های آن را متناسب با مقادير موجود در query تنظيم و کلاس سفارشی را به يک ArrayList اضافه نمود . در ادامه می توان اشياء سفارشی را Cache نمود . روش فوق علاوه بر افزايش کارآئی ، قابليت پشتيبانی را نيز بهتر خواهد کرد . همچنين می توان اين مجموعه از کلاس های سفارشی شده را به يک کنترل وب داده ASP.NET ( نظير DataList, DataGrid و يا Repeater ) نيز نسبت داد (مشابه استفاده از يک DataSet و يا DataReader ) .
يکی ديگر از مواردی که می تواند دلايل استفاده از يک DataSet را در برنامه های وب توجيه نمايد ، زمانی است که قصد دستيابی تصادفی به داده هائی خاص در بين تعدادی رکورد را داشته باشيم . چراکه رکوردهای فوق ممکن است بدفعات استفاده گردند . مثلا" فرض کنيد قصد استفاده از يک master/detail DataGrid را داريم که در آن يک ستون از DataGrid شامل رکورد مادر و ساير ستون ها شامل DataGrid ديگر ( مرتبط با سطر فرزند) باشد . در چنين مواردی استفاده از يک DataSet به منظور جمع آوری تمامی رکوردهای فرزند از بانک اطلاعاتی در مقابل اين روش که برای هر سطر DataGrid يک query را استفاده نمود ، ترجيح داده می شود . کارآئی روش فوق به تعداد سطرهای موجود در جدول مادر بستگی خواهد داشت . از آنجائيکه يک DataSet سی مرتبه کندتر از يک DataReader است ، اگر بيش از سی رکورد در جدول مادر وجود دارد که قصد نمايش آنان را داريم ، استفاده از يک DataSet می تواند گزينه ای معقول تر در اين زمينه باشد تا اين که برای هر رکورد مادر يک query را اجراء نمود .
منبع: http://www.4guysfromrolla.com




نظرات کاربران
ارسال نظر
با تشکر، نظر شما پس از بررسی و تایید در سایت قرار خواهد گرفت.
متاسفانه در برقراری ارتباط خطایی رخ داده. لطفاً دوباره تلاش کنید.
مقالات مرتبط