1. مهمان گرامی، جهت ارسال پست، دانلود و سایر امکانات ویژه کاربران عضو، ثبت نام کنید.
    بستن اطلاعیه

تفاوت DataReader و DataSet دو شی ارائه شده در ADO.NET

شروع موضوع توسط minaaa ‏29/1/11 در انجمن .Net

  1. کاربر پیشرفته

    تاریخ عضویت:
    ‏9/12/10
    ارسال ها:
    19,773
    تشکر شده:
    6,457
    امتیاز دستاورد:
    113
    مبانی و اصول اولیه 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()​
    </pre>


    [SIZE=+0]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
    را نشان می دهد : [/SIZE] کد:
    ' 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 ...​
    </pre>


    [SIZE=+0]همانگونه که در کد فوق مشاهده می گردد ، متد Fill
    مربوط به شی DataAdapter مسئولیت پر نمودن DataSet را با توجه به query
    مورد نظر برعهده دارد . در پس پرده ، از یک DataReader به منظور خواندن
    نتایج اجرای query و پر نمودن DataSet استفاده می گردد. DataSet یک شی
    داده disconnected است. این بدان معنی است که پس از استقرار داده در
    DataSet ، می توان connection را غیرفعال ( close ) و همچنان بررسی و
    پردازش لازم بر روی داده های موجود در DataSet را انجام داد .

    با توجه به این که DataSet یک مجموعه از داده های غیرمتصل جداگانه را
    ارائه می نماید ، امکان ویرایش و دستیابی تصادفی به اطلاعات موجود در آن
    وجود خواهد داشت . دو ویژگی فوق در DataReader
    [/SIZE][SIZE=+0]وجود
    ندارند . علاوه بر موارد فوق ، DataSet دارای پتانسیل های قدرتمندی به
    منظور کار با اسناد XML است . مثلا" می توان با استفاده از متد WriteXml
    اطلاعات موجود در یک DataSet را درون یک فایل XML مستقر و یا می توان
    اطلاعات موجود در یک فایل XML را با استفاده از متد ReadXml شی DataSet
    خواند و در یک DataSet مستقر نمود .
    [/SIZE]

    [SIZE=+0]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
    در یکی از دو مورد زیر می تواند مفید واقع شود : [/SIZE]

    • [SIZE=+0] [/SIZE][SIZE=+0]
    • برنامه های Desktop
      : فرض کنید دارای یک برنامه ورود اطلاعات desktop-based باشیم . یک کاربر
      برنامه را اجراء ، داده هائی خاص را از برخی بانک های اطلاعاتی load و پس
      از اعمال تغییرات لازم آنان را در بانک اطلاعاتی ذخیره می نماید . وضعیت
      فوق یک حالت ایده آل برای DataSet است و امکان خواندن داده ها از درون یک
      DataSet مستقر در حافظه کامپیوتر سرویس گیرنده ، وجود خواهد داشت . بدین
      ترتیب کاربران می توانند با داده ها بدون نیاز به ارتباط مستمر با بانک
      اطلاعاتی کار کنند . پس از اتمام عملیات ویرایش داده ها ، به منظور اعمال
      تغییرات لازم می توان از یک Batch update استفاده نمود . از آنجائیکه
      DataSet یک منبع ذخیره سازی داده disconnected است ، امکان دستیابی offline
      به داده ها
      وجود خواهد داشت .

      چنین وضعیتی ممکن است در یک برنامه وب نیز محقق
      گردد و لازم باشد که کاربران با برنامه وب همانند آنچه اشاره گردید ،
      ارتباط برقرار نمایند . آنان یک صفحه وب را مشاهده نموده و پس از اعمال
      تغییرات لازم ، صرفا" با فعال نمودن یک دکمه Update تغییرات را در بانک
      اطلاعاتی ثبت نمایند .بانک اطلاعاتی مورد نظر بهنگام نمی گردد تا زمانی که
      دکمه Update فعال گردد . در چنین مواردی می توان از یک Dataset مبتنی بر
      Session استفاده نمود.
    • ارسال و یا دریافت از راه دور اطلاعات از بانک اطلاعاتی به منظور برقراری ارتباط بین پلت فورم های متفاوت : با توجه به این موضوع که یک DataSet
      می تواند به سادگی درون یک فایل XML قرار داده شود و یا از آن خوانده
      شوند ، به عنوان اولین کاندید برای ارسال اطلاعات بین پلت فورم های متفاوت
      مطرح می باشد .مثلا" در صورتی که قصد برگرداندن داده بانک اطلاعاتی را از
      طریق یک سرویس وب داشته باشید ، یکی از روش های موجود در این زمینه این
      است که داده های بانک اطلاعاتی درون یک DataSet قرار داده شوند و در ادامه
      با استفاده از متد سرویس وب، DataSet برگردانده شود . در چنین حالتی
      DataSet به صورت اتوماتیک درون یک فایل XML قرار داده شده و ارسال می گردد
      .
      [/SIZE]
    [SIZE=+0]علل استفاده از 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
    را اجراء نمود . [/SIZE]