2012-03-21 17 views
14

यदि कॉल करने जा रहे तरीकों/कार्यों में एक खुले SqlConnection की आवश्यकता शामिल है, तो मैं इसे उस विधि में खोलूंगा जो फ़ंक्शन को कॉल कर रहा है। उदाहरण के लिए:क्या एक पैरामीटर के रूप में एक खुला SqlConnection पास करना सबसे अच्छा है, या प्रत्येक विधि में एक नया कॉल करें?

protected static void btnSubmit(){ 
    conn.Open(); 
    myMethod(someParam, conn); 
    conn.Close(); 
} 

protected static void myMethod(object someParam, SqlConnection conn){ 
    //Some SQL commands etc here.. 
} 

मैं यह करने के लिए इतना है कि मैं:

  • केवल कभी खुले और बंद प्रक्रिया प्रति 1 SqlConnection

हालांकि, यह बेहतर होगा ताकि तरह मेरे कोड की संरचना करने के :

protected static void btnSubmit(){ 
    myMethod(someParam); 
} 

protected static void myMethod(object someParam){ 
    SqlConnection conn = New SqlConnection("....."); 
    conn.Open(); 
    //Some SQL commands etc here.. 
    conn.Close(); 
} 

मुझे इस तरह की संरचना करने का लाभ यह है:

  • मैं बाद में लाइन पद्धति अब एक एसक्यूएल आदेश है नीचे, वहाँ एक अप्रयुक्त पैरामीटर हर बार
बुलाया जा रहा है नहीं है, तो प्रत्येक विधि के लिए एक अतिरिक्त पैरामीटर
  • पारित करने के लिए की जरूरत नहीं है

    नुकसान मैं यह करने के लिए देखते हैं, है:

    • तो myMethod एक पुनरावर्ती विधि है, तो जब वह खुद कहता है इसकी एक और SqlConnection खोलने जा रहा, और इतने पर, और इतने पर ..
    • यदि btnSubmit कई विधियों को कॉल कर रहा है, जिन्हें सभी को SQL कनेक्शन की आवश्यकता होती है, तो प्रत्येक एक नया कनेक्शन खोलने और बंद करने जा रहा है।

    ऐसा करने का सबसे अच्छा तरीका क्या है, और इसका सबसे अधिक अभ्यास किया जाता है?

  • उत्तर

    16

    ADO.NET कनेक्शन पूलिंग का उपयोग करता है, इसलिए यह स्वचालित रूप से पहले ही खोला कनेक्शन का उपयोग करता है, भले ही आपको लगता है कि आप एक नया कनेक्शन खोल रहे हैं। इसे ध्यान में रखते हुए, आपके कोड (पैरामीटर के रूप में) के माध्यम से कनेक्शन पारित करने का वास्तव में कोई कारण नहीं है। यह आपके कोड को उसी प्रदर्शन के साथ अधिक क्लीनर बना देगा जब आप पैरामीटर के रूप में कनेक्शन पास कर रहे हों।

    अधिक जानकारी here

    इसके अलावा (और यह वास्तव में महत्वपूर्ण है), कृपया, कीवर्ड "का उपयोग कर" का उपयोग करें। इस तरह, आपको कनेक्शन और सफाई को बंद करने के साथ निपटना नहीं होगा, क्योंकि आपका कोड अब लिखा गया है, कनेक्शन को बंद करने से निपटता नहीं है, इसलिए कुछ अपवाद के मामले में आप कनेक्शन सीमा को मारने के साथ समाप्त हो सकते हैं आपका सर्वर

    using(var connection = new SqlConnection(<connection_string>)) 
    { 
        connection.Open(); 
        using(var command = connection.CreateCommand()) 
        { 
    
        } 
    } 
    

    जैसा कि आप देख सकते हैं, वहाँ, connection.Close (कॉल करने के लिए) या अपवाद और अपने finally ब्लॉक में कनेक्शन बंद करने के साथ सौदा कोई जरूरत नहीं है क्योंकि उस के लिए एक "काम" है: कुछ इस तरह के साथ जाने के "उपयोग" ब्लॉक।

    इसके अलावा, एक महत्वपूर्ण नोट ... लेनदेन कनेक्शन मतदान के माध्यम से पारित नहीं किया जाता है, इसलिए यदि आप अपना लेनदेन विधि कॉल में रखना चाहते हैं, तो आपको अपना कनेक्शन पारित करना होगा (और यही कारण है कि मैं सोच सकता हूं आपको ऐसा क्यों करना चाहिए)।

    +0

    तो यदि मैं 100 अलग-अलग SQLConnection ऑब्जेक्ट्स खोलता हूं, तो सभी एक ही डेटाबेस/लॉगिन के लिए, यह प्रसंस्करण पर कोई अतिरिक्त तनाव नहीं डाल रहा है? अतिरिक्त जानकारी के लिए – Curt

    +0

    चीयर्स। तो 'myMethod' में अपना' उपयोग 'कथन डालने का अच्छा अभ्यास है (मेरे उदाहरण का उपयोग करके)? प्रदर्शन उद्देश्यों के लिए मैंने हमेशा इसे टाला है, लेकिन अगर इससे कोई फर्क नहीं पड़ता है तो यह इतना साफ होगा! – Curt

    +1

    यदि आप इसे विश्वास नहीं करते हैं, तो परीक्षण करें और इसे आजमाएं :) आप देखेंगे कि कोई अंतर नहीं है (कम से कम ध्यान देने योग्य नहीं)। कनेक्शन पूल में एक संपत्ति है कि अधिकतम पूल आकार क्या है (100 एक डिफ़ॉल्ट मान है, मुझे लगता है), यहां एक नज़र डालें: http://msdn.microsoft.com/en-us/library/8xx3tyca(v= vs.71) .aspx "कनेक्शन स्ट्रिंग कीवर्ड के साथ कनेक्शन पूलिंग को नियंत्रित करना" अनुभाग –

    10

    उपयोग करने के लिए सबसे अच्छा पैटर्न Repository + UnitOfWork पैटर्न है।

    तो भंडार बनाया गया है और यूनिटऑफवर्क्स पास किया गया है जिसमें कनेक्शन है। काम पूरा होने के बाद यूनिटऑफवर्क का निपटारा किया जाता है।

    // Pseudocode 
    using(UnitOfWork uow = new UnitOfWork()) 
    { 
        Repository.Init(uow); 
        Repository.SaveInDb(stuff); 
    } 
    

    और काम की इकाई:

    // PseudoCode 
    class UnitOfWork : IDisposable 
    { 
        public UnitOfWork() 
        { 
         conn = new SqlConnection(); 
         conn.Open(); 
        } 
    
        public void Dispose() 
        { 
         conn.Close(); 
        } 
    
    .... 
    
    } 
    

    यह जो मैं हमेशा प्रयोग करते हैं।

    कुछ लोग सरल दृष्टिकोण पसंद करते हैं जहां रिपोजिटरी कनेक्शन का मालिक है। यह आसान है लेकिन यदि आपको एकाधिक भंडारों में लेनदेन करने की आवश्यकता है, तो यह काम नहीं करेगा।

    +0

    +1 इस तथ्य की ओर इशारा करते हुए भी थोड़ा सा है कि डेटाबेस अद्यतन करते समय लेनदेन सीमाओं पर विचार किया जाना चाहिए। – mwardm