SqlDataAdapter बनाम SqlDataReader


130

एक DB से डेटा प्राप्त करने के लिए SqlDataAdapter बनाम SqlDataReader का उपयोग करने के बीच अंतर क्या हैं?

मैं विशेष रूप से उनके पेशेवरों और विपक्षों के साथ-साथ उनकी गति और स्मृति प्रदर्शन में देख रहा हूं।

धन्यवाद

जवाबों:


193

SqlDataReader:

  • कनेक्शन पूरा होने तक खुला रहता है (इसे बंद करना न भूलें!)।
  • आम तौर पर केवल एक बार से अधिक पुनरावृत्त किया जा सकता है
  • डेटाबेस में वापस अपडेट करने के लिए उतना उपयोगी नहीं है

दूसरी ओर, यह:

  • पूरे परिणाम सेट के बजाय एक समय में मेमोरी में केवल एक ही रिकॉर्ड होता है (यह बहुत बड़ा हो सकता है )
  • के रूप में उपवास के बारे में है कि आप एक पुनरावृत्ति के लिए प्राप्त कर सकते हैं
  • आपको जल्द ही परिणाम संसाधित करने की अनुमति देता है (पहला रिकॉर्ड उपलब्ध होने के बाद)। कुछ क्वेरी प्रकारों के लिए यह एक बहुत बड़ी बात हो सकती है।

SqlDataAdapter / डेटासेट

  • आपको लोडिंग डेटा पूरा करते ही कनेक्शन बंद कर देता है, और आपके लिए इसे स्वचालित रूप से बंद भी कर सकता है
  • सभी परिणाम स्मृति में उपलब्ध हैं
  • आप जितनी बार चाहें उतनी बार उस पर पुनरावृति कर सकते हैं, या यहां तक ​​कि सूचकांक द्वारा एक विशिष्ट रिकॉर्ड भी देख सकते हैं
  • डेटाबेस में वापस अपडेट करने के लिए कुछ अंतर्निहित संकाय हैं

की कीमत पर:

  • बहुत अधिक मेमोरी का उपयोग
  • आप तब तक इंतजार करते हैं जब तक कि उसमें से किसी का उपयोग करने से पहले सभी डेटा लोड न हो जाए

तो वास्तव में यह इस बात पर निर्भर करता है कि आप क्या कर रहे हैं, लेकिन मैं एक DataReader को प्राथमिकता देता हूं, जब तक कि मुझे किसी ऐसी चीज की जरूरत नहीं है जो केवल डेटासेट द्वारा समर्थित हो। SqlDataReader केवल-पढ़ने के लिए ग्रिड के लिए सामान्य डेटा एक्सेस मामले के लिए एकदम सही है।

अधिक जानकारी के लिए, आधिकारिक Microsoft दस्तावेज़ देखें


5
डेटासेट एक इन-मेमोरी डेटास्टोर है, जबकि डेटारीडर डेटा प्राप्त करने का एक माध्यम है। एक हल्के नोट पर, आप डेटासेट पर Linq क्वेरी चला सकते हैं, लेकिन डेटाट्रेडर पर नहीं।
पार्थ चौधरी

दरअसल, थोड़ा अतिरिक्त कोड के साथ आप निश्चित रूप से एक datareader पर linq क्वेरीज़ (या, कम से कम एक क्वेरी) चला सकते हैं। बस अपने while (reader.Read())लूप के अंदर एक IDataRecord के रूप में DataReader कास्ट को वापस लाने के लिए एक इटरेटर ब्लॉक का उपयोग करें ।
जोएल कोएहॉर्न 21

7
यह उत्तर भ्रामक है। यदि आप अपने SqlConnection और SqlDataReader ऑब्जेक्ट्स को "स्टेटमेंट्स" (जैसा कि वैसे भी, जब से वे आईडीसोपायरीली हैं) का उपयोग करके लपेटते हैं, तो कनेक्शन अपने आप बंद हो जाएगा। और आप SqlDataReader के साथ एक DataSet का उपयोग कर सकते हैं: DataSet.Load (SqlDataReader) को कॉल करें।
रिकएनजेड डिक्

4
@RickNZ आप के लिए चीजों को बंद करने के लिए बयानों का उपयोग कर भरोसा करने के लिए बहुत जल्दी मत बनो। वे ऑब्जेक्ट के डिस्पोज़ () विधि को कहते हैं, न कि क्लोज़ () विधि, और मैं कम से कम एक मामले में चला गया हूं, जहां डिस्पोज़ ने वास्तव में मेरे लिए ऑब्जेक्ट को बंद नहीं किया है। उपयोग करने वाले ब्लॉक के अंदर एक स्पष्ट कॉल को बंद विधि में शामिल करना हमेशा सबसे अच्छा होता है।
Cdaragorn

5
MSC डॉक्स @Caragorn आमतौर पर क्लोज़ () बनाम डिस्पोज़ () के बारे में बहुत स्पष्ट होते हैं। उदाहरण के लिए SqlConnection के मामले में, डॉक्स कहते हैं कि क्लोज़ () और डिस्पोज़ () कार्यात्मक रूप से समतुल्य हैं। मुझे क्लोज़ () को कॉल करने में कोई आपत्ति नहीं है, लेकिन डिस्पोज़ () के लिए कॉल सभी IDisposables के लिए होनी चाहिए - और सबसे साफ तरीका यह है कि एक उपयोग कथन के साथ है। ऐसे मामलों में जहां आप जानते हैं कि डिस्पोज़ () क्लोज़ को कॉल नहीं करता है (), तो आपको क्लोज़ () को अंत में ब्लॉक करना चाहिए यदि आप कर सकते हैं, तो ब्लॉकिंग ब्लॉक के भीतर नहीं (इसलिए यह तब भी कॉल किया जाता है जब कोई अपवाद हो)।
रिकएनजेड

17

इसका जवाब काफी व्यापक हो सकता है।

अनिवार्य रूप से, मेरे लिए प्रमुख अंतर जो आमतौर पर मेरे निर्णयों को प्रभावित करता है जिस पर उपयोग करने के लिए यह है कि SQLDataReader के साथ, आप डेटाबेस से डेटा "स्ट्रीमिंग" कर रहे हैं। SQLDataAdapter के साथ, आप डेटाबेस से डेटा को एक ऐसी वस्तु में निकाल रहे हैं, जिसे स्वयं आगे बढ़ाया जा सकता है, साथ ही साथ CRUD संचालन भी किया जा सकता है।

स्पष्ट रूप से डेटा की एक धारा के साथ SQLDataReader तेजी से है, लेकिन आप केवल एक समय में एक रिकॉर्ड की प्रक्रिया कर सकते हैं। SQLDataAdapter के साथ, आपके पास अपने कोड के साथ काम करने / पास करने के लिए डेटाबेस से आपकी क्वेरी से मेल खाने वाली पंक्तियों का एक पूरा संग्रह है।

चेतावनी: यदि आप SQLDataReader, ALWAYS, ALWAYS, ALWAYS का उपयोग कर रहे हैं, तो सुनिश्चित करें कि आप कनेक्शन को बंद करने के लिए उचित कोड लिखते हैं क्योंकि आप SQLDataReader के साथ कनेक्शन खुला रख रहे हैं। ऐसा करने में विफलता, या परिणामों को संसाधित करने में त्रुटि के मामले में कनेक्शन को बंद करने के लिए उचित त्रुटि हैंडलिंग, कनेक्शन लीक के साथ आपके आवेदन को क्रिप्‍पल करेगा ।

मेरे VB को क्षमा करें, लेकिन SqlDataReader का उपयोग करते समय आपके पास कम से कम कोड होना चाहिए:

Using cn As New SqlConnection("..."), _
      cmd As New SqlCommand("...", cn)

    cn.Open()
    Using rdr As SqlDataReader = cmd.ExecuteReader()
        While rdr.Read()
            ''# ...
        End While
    End Using
End Using     

समतुल्य सी #:

using (var cn = new SqlConnection("..."))
using (var cmd = new SqlCommand("..."))
{
    cn.Open();
    using(var rdr = cmd.ExecuteReader())
    {
        while(rdr.Read())
        {
            //...
        }
    }
}

यदि आपका लक्ष्य db पर एक चुनिंदा क्वेरी का उपयोग करके डेटा प्राप्त करना है, और केवल अलग-अलग पंक्तियों में इस डेटा का उपयोग करना है, तो स्पष्ट पंक्ति, आदि पर जाएं, फिर आप SQLDatareader का उपयोग कर सकते हैं और इसे dtable.Load (rdr) का उपयोग करके एक डेटाटेबल में लोड कर सकते हैं। फिर इस डिटैटेबल के भीतर ऊपर और नीचे ब्राउज़ करें। आप DataAdapter के बजाय इस विधि का उपयोग कर सकते हैं ...
चर

14

SqlDataAdapter का उपयोग आमतौर पर DataSet या DataTable को भरने के लिए किया जाता है और इसलिए आपके कनेक्शन बंद होने के बाद डेटा तक आपकी पहुंच होगी (डिस्कनेक्ट की गई पहुंच)।

SqlDataReader एक तेज़ फ़ॉरवर्ड-ओनली और कनेक्टेड कर्सर है जो आमतौर पर डेटासेट / डेटाटेबल भरने की तुलना में अधिक तेज़ होता है।

इसके अलावा, SqlDataReader के साथ, आप एक समय में अपने डेटा एक रिकॉर्ड के साथ सौदा करते हैं, और मेमोरी में कोई डेटा नहीं रखते हैं। स्पष्ट रूप से एक DataTable या DataSet के साथ, आपके पास ओवरहेड एक मेमोरी आवंटन है।

यदि आपको अपने डेटा को मेमोरी में रखने की आवश्यकता नहीं है, तो केवल सामान प्रदान करने के लिए, SqlDataReader के लिए जाएं। यदि आप डिस्कनेक्ट किए गए फैशन में अपने डेटा से निपटना चाहते हैं, तो डेटासेट या डेटाटेबल भरने के लिए डेटा एडेप्टर चुनें।


10

डेटाबेस से इन-मेमरी डेटासेट / डेटाटेबल को पॉप्युलेट करने के लिए SqlDataAdapter का उपयोग करें। फिर आपके पास कनेक्शन को बंद / डिस्पोज़ करने, मेमोरी में पास / सेट करने योग्य / पास करने का लचीलापन है। फिर आप डेटा में हेरफेर कर सकते हैं और इसे डीबी में वापस डाल सकते हैं डेटा एडाप्टर का उपयोग करते हुए, सम्मिलितकोमांड / अपडेटडोमैंड के साथ संयोजन में।

तीव्र, निम्न-स्मृति पदचिह्न डेटा एक्सेस की आवश्यकता के बिना लचीलेपन की आवश्यकता के लिए एक SqlDataReader का उपयोग करें, उदाहरण के लिए अपने व्यावसायिक तर्क के आसपास डेटा पास करना। यह बड़े डेटा संस्करणों की त्वरित, कम-मेमोरी उपयोग पुनर्प्राप्ति के लिए अधिक इष्टतम है क्योंकि यह सभी डेटा को एक बार में सभी मेमोरी में लोड नहीं करता है - SqlDataAdapter दृष्टिकोण के साथ, डेटासेट / डेटाटेबल सभी डेटा से भरा होगा बहुत सी पंक्तियाँ और स्तंभ हैं, जिन्हें रखने के लिए बहुत सारी मेमोरी की आवश्यकता होगी।


0

भरण फ़ंक्शन आंतरिक रूप से DataReader का उपयोग करता है। यदि आपका विचार "कौन सा अधिक कुशल है?", तो एक तंग लूप में एक DataReader का उपयोग करके जो संग्रह रिकॉर्ड-दर-रिकॉर्ड को पॉप्युलेट करता है, सिस्टम पर DataAdapter.Fill का उपयोग करने के समान लोड होने की संभावना है।

(System.Data.dll, System.Data.Common.DbDataAdapter, FillInternal।)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.