2009-08-31 39 views
1

我有以下方法應該是我的應用程序的通用「保存到SQL」方法。使用我的存儲過程時遇到問題

protected void EjecutarGuardar(string ProcedimientoAlmacenado, object[] Parametros) 
     { 
      SqlConnection Connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); 

      SqlCommand Command = Connection.CreateCommand();    
      Command.CommandType = CommandType.StoredProcedure; 
      foreach (object X in Parametros) 
      { 
       Command.Parameters.Add(X); 
      }    

      Connection.Open(); 
      Command.ExecuteNonQuery(); 
      Connection.Close(); 

      Connection.Dispose(); 
     } 

我必須通過StoredProcedure的名稱和一個填充參數的數組。我有點失落。我應該在哪裏使用存儲過程的名稱「ProcedimientoAlmacenado」?

我在想也許Command.Command ????? somethign?但我迷失了。任何幫助?

編輯:爲了簡單起見,我們假設我的數據庫中有一個名爲「ABC」的存儲過程。我怎麼能將它與我的代碼中的SqlCommand「Command」相關聯?

回答

3

Command.CommandText= ProcedimientoAlmacenado

參數必須有名字了。 Parametros數組是否包含SqlParameter對象或通用C#對象?

如果參數是通用的C#的對象,是更好的名稱和值的字典經過:

protected void EjecutarGuardar(string ProcedimientoAlmacenado, 
    Dictionary<string, object> Parametros) 
{ 
    using (SqlConnection Connection = new SqlConnection(...)) 
    { 
     Connection.Open(); 
     SqlCommand Command = Connection.CreateCommand() 
     Command.CommandText = ProcedimientoAlmacenado; 
     Command.Connection = Connection;  
     Command.CommandType = CommandType.StoredProcedure; 
     foreach (string name in Parametros.Keys) 
     { 
      Command.Parameters.AddWithValue(name, Parametros[name] ?? DBNull.Value); 
     }    
     Command.ExecuteNonQuery(); 
    } 
} 

這是一個快速和骯髒的方法。請注意,這種方法通常會遇到問題,因爲AddWithValue會爲字符串傳遞NVARCHAR類型的參數,而不是VARCHAR,並且使用臨時SQL可能會導致VARCHAR列上的索引SARG能力問題(因爲轉換始終是從VARCHAR到NVARCHAR,而不是反之亦然)。但是,使用存儲過程不是這樣的問題,因爲過程具有類型參數,因此如果過程是使用參數類型VARCHAR創建的,則會對VARCHAR發生強制強制。

您也將有大約傳遞NULL參數,問題所以你需要做這樣的事情,參數必須是DBNull.Valuenull

Command.Parameters.AddWithValue(name, Parametros[name] ?? DBNull.Value); 

在高性能系統中這種方法也污染了執行不必要地緩存,因爲AddWithValue將傳遞NVARCHAR(<exact length of the string>)類型的參數,而不是NVARCHAR(<length of the database type>)。因此,Paramaters.AddWithValue("@name", "John")Parameters.AddwithValue("@name", "Doe")將在緩存中創建兩個不同的計劃,因爲一個是使用NVARCHAR(4)類型的參數調用的,另一個使用參數NVARCHAR(3),並且它們被SQL計劃緩存視爲不同類型。這對簡單的項目不是問題,但對於更復雜和更高性能的項目,建議您明確設置參數類型。

我的建議是避免使用這種通用的一勞永逸的過程,而是用適當的類型參數爲每個數據庫過程編寫一個帶有顯式C#包裝的數據訪問層。強類型數據集實際上可以做到這一點,另一種選擇(我最喜歡的和我總是使用的)是使用創建C#包裝器的XSLT樣式表從XML文件生成整個數據訪問員。源XML當然是從數據庫元數據本身提取的。

+0

他們只是普通的對象。我的計劃是將一堆東西(int,string,bool)加載到object []數組中,然後使用foreach加載參數。這將工作正確嗎? :) – 2009-08-31 03:20:28

+0

不,您需要傳遞參數名稱 - 值的字典併爲每個參數分配名稱。 – 2009-08-31 03:22:25

+0

您的存儲過程規定了可以添加到命令對象的參數。 – 2009-08-31 03:22:33

0
Command.ComandText = "storedProcName"; 
0

Command.CommandText = "ProcedimientoAlmacenado";之前或之後Command.CommandType = CommandType.StoredProcedure;這不是強制性的,但那個是我做的方式。

0

設置SqlCommand對象的CommandText屬性到您的存儲過程的名稱:

Command.CommandText = "MyStoredProcedureName";