2010-04-23 14 views
8

मैं एक व्यापार परत है कि एक कॉन स्ट्रिंग और इतनेक्या SQLCommand को पैरामीटर के रूप में पास करना ठीक है?

public void PopulateLocalData() 
    { 
     System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(); 
     cmd.CommandType = System.Data.CommandType.StoredProcedure; 
     cmd.CommandText = "usp_PopulateServiceSurveyLocal"; 
     DataLayer.DataProvider.ExecSQL(ConnString, cmd); 
    } 

की तरह एक डेटा स्तर पर एक SqlCommand गुजरता dataLayer तो बस इतना

 public static int ExecSQL(string sqlConnString, System.Data.SqlClient.SqlCommand cmd) 
    { 
     int rowsAffected; 
     using (SqlConnection conn = new SqlConnection(sqlConnString)) 
     { 
      conn.Open(); 
      cmd.Connection = conn; 
      rowsAffected = cmd.ExecuteNonQuery(); 
      cmd.Dispose(); 
     } 
     return rowsAffected; 
    } 

तरह एसक्यूएल कार्यान्वित करने के लिए मेरे लिए यह ठीक है है SQLCommand को इस तरह के पैरामीटर के रूप में पास करें या ऐसा करने का एक बेहतर स्वीकार्य तरीका है। मेरी चिंताओं में से एक यह है कि क्वेरी को निष्पादित करते समय त्रुटि उत्पन्न होती है cmd.dispose लाइन कभी निष्पादित नहीं होगी। क्या इसका मतलब यह है कि यह स्मृति का उपयोग जारी रखेगा जो कभी जारी नहीं किया जाएगा?

अद्यतन:

एरिक की सलाह के बाद मैं और अधिक स्पष्ट रूप से व्यापार और डेटा परतों विभाजित तो व्यापार परत में विधि इस

public void PopulateLocalData() 
    { 
     DataLayer Data = new DataLayer(this.ConnString); 
     Data.UpdateLocalData(); 
    } 

और विधि है कि dataLayer में कहा जाता है की तरह लग रहा इस तरह दिखता है ।

 public void UpdateLocalData() 
    { 
     using (SqlConnection conn = new SqlConnection(this.ConnString)) 
     using(SqlCommand cmd = new SqlCommand()) 
     { 
      cmd.CommandType = System.Data.CommandType.StoredProcedure; 
      cmd.CommandText = "usp_PopulateServiceSurveyLocal"; 
      conn.Open(); 
      cmd.Connection = conn; 
      cmd.ExecuteNonQuery(); 
     } 
    } 

इस तरह यह बहुत स्पष्ट है कि SQLCommand और SQLConnection दोनों को ठीक से निपटान किया जाएगा। धन्यवाद।

public static int ExecSQL(string sqlConnString, System.Data.SqlClient.SqlCommand cmd) 
{ 
    int rowsAffected; 
    try 
    { 
     using (SqlConnection conn = new SqlConnection(sqlConnString)) 
     { 
      conn.Open(); 
      cmd.Connection = conn; 
      rowsAffected = cmd.ExecuteNonQuery(); 
     } 
    } finally { 
     cmd.Dispose(); 
    } 
    return rowsAffected; 
} 

साथ ही, मैं आम तौर पर अपने व्यवसाय और डेटा परतों से अधिक तुम क्या अलग:

उत्तर

6

आदर्श रूप से, आपकी व्यावसायिक परत को आपकी डेटा परत के कार्यान्वयन विवरण से अवगत नहीं होना चाहिए। इसलिए, क्या आप SqlCommand ऑब्जेक्ट्स या एनएचबीरनेट जैसी कुछ चीज़ों के साथ डेटा लेयर को कार्यान्वित करते हैं, तो व्यापार परत के लिए अप्रासंगिक होना चाहिए। इससे सैद्धांतिक रूप से आपकी डेटा परत को 'बाहर निकालना' आसान हो जाता है और इसे दूसरे के साथ बदल दिया जाता है।

संक्षेप में: SqlCommand को व्यवसाय परत से डेटा परत तक पास करना मेरी आंखों में अच्छा अभ्यास नहीं माना जाता है।

Dispose() के बारे में: यदि आप एक का उपयोग कर-कथन (using(SqlConnection ...)) की तरह प्रयोग कर रहे हैं, Dispose() विधि कथन का उपयोग के अंत में स्वचालित रूप से कहा जाता है। आपको इसे मैन्युअल रूप से करने की ज़रूरत नहीं है।

+0

: सामान्य नियम अब भी है - लेकिन यह एक कार्यान्वयन विस्तार है कि आप पर भरोसा नहीं करना चाहिए। हालांकि कोई उपयोग नहीं कर रहा है (SqlCommand ...) ... और समस्या यह है कि अगर कुछ विफल रहता है तो आदेश ठीक से निपटान नहीं किया जा सकता है। कनेक्शन ठीक है। – cHao

+0

जहां तक ​​मुझे पता है, (SqlCommand cmd = ...) का उपयोग पूरी तरह से मान्य है। –

-1

खैर शुरुआत के लिए, आप इसे करने के लिए बदल सकता है। मेरी व्यावसायिक परत डेटा परत में "GetLocalSurvey" विधि को कॉल करेगी, जो सभी SQL बकवास को संभालेगी।

0

क्यों आप इसे इस के लिए बदल नहीं है:

public static int ExecProcedure(string sqlConnString, string procedureName) 
{ 
    using (var cmd = new System.Data.SqlClient.SqlCommand()) 
    { 
     cmd.CommandType = System.Data.CommandType.StoredProcedure; 
     cmd.CommandText = procedureName; 
     int rowsAffected; 
     using (SqlConnection conn = new SqlConnection(sqlConnString)) 
     { 
      conn.Open(); 
      cmd.Connection = conn; 
      return cmd.ExecuteNonQuery(); 
     } 
    } 
} 

आप अतिरिक्त पैरामीटर करना चाहते हैं? ओवरलोड, रिफैक्टर बनाएं। सामान्य समारोह में सबसे अधिक कोड साझा करें। हर जगह new System.Data.SqlClient.SqlCommand() बनाना गलत दृष्टिकोण है।

0

कमांड बनाने वाला व्यक्ति इसे निपटाने के लिए ज़िम्मेदार होना चाहिए। जब क्वेरी cmd.dispose लाइन होगा क्रियान्वित करने में कोई त्रुटि होती है तो

public void PopulateLocalData() 
{ 
    using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand()) 
    { 
     cmd.CommandType = System.Data.CommandType.StoredProcedure; 
     cmd.CommandText = "usp_PopulateServiceSurveyLocal"; 
     DataLayer.DataProvider.ExecSQL(ConnString, cmd); 
    } 
} 

एक मेरी चिंताओं में से है: इस के लिए सबसे आसान तरीका है इस तरह ExecSql से cmd.Dispose का कॉल निकालना और इसके बजाय फोन अपने समारोह है कभी निष्पादित नहीं करें।क्या इसका मतलब यह है कि यह स्मृति का उपयोग जारी रखेगा जो कभी जारी नहीं किया जाएगा?

संयोग से, SqlClient.SqlCommand को निपटाने की आवश्यकता नहीं है। (SqlCeClient.SqlCeCommand, उदाहरण के लिए, निपटारा करने के लिए की जरूरत है ... करता है) यह IDisposable लागू करता है, तो यह निपटाने

संबंधित मुद्दे