zoukankan      html  css  js  c++  java
  • 【2016-11-2】【坚持学习】【Day17】【微软 推出的SQLHelper】

    从网络上找到 微软原版本的SQLHelper,很多行代码。认真看了,学习了。
     代码: 
       1 using System;
       2 using System.Data;
       3 using System.Xml;
       4 using System.Data.SqlClient;
       5 using System.Collections;
       6 
       7 namespace Helper
       8 {
       9     /// <summary>
      10     /// The SqlHelper class is intended to encapsulate high performance, scalable best practices for 
      11     /// common uses of SqlClient
      12     /// </summary>
      13     public sealed class SqlHelper
      14     {
      15         #region private utility methods & constructors
      16 
      17         // Since this class provides only static methods, make the default constructor private to prevent 
      18         // instances from being created with "new SqlHelper()"
      19         private SqlHelper() { }
      20 
      21         /// <summary>
      22         /// This method is used to attach array of SqlParameters to a SqlCommand.
      23         /// 
      24         /// This method will assign a value of DbNull to any parameter with a direction of
      25         /// InputOutput and a value of null.  
      26         /// 
      27         /// This behavior will prevent default values from being used, but
      28         /// this will be the less common case than an intended pure output parameter (derived as InputOutput)
      29         /// where the user provided no input value.
      30         /// </summary>
      31         /// <param name="command">The command to which the parameters will be added</param>
      32         /// <param name="commandParameters">An array of SqlParameters to be added to command</param>
      33         private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters)
      34         {
      35             if (command == null) throw new ArgumentNullException("command");
      36             if (commandParameters != null)
      37             {
      38                 foreach (SqlParameter p in commandParameters)
      39                 {
      40                     if (p != null)
      41                     {
      42                         // Check for derived output value with no value assigned
      43                         if ((p.Direction == ParameterDirection.InputOutput ||
      44                             p.Direction == ParameterDirection.Input) &&
      45                             (p.Value == null))
      46                         {
      47                             p.Value = DBNull.Value;
      48                         }
      49                         command.Parameters.Add(p);
      50                     }
      51                 }
      52             }
      53         }
      54 
      55         /// <summary>
      56         /// This method assigns dataRow column values to an array of SqlParameters
      57         /// </summary>
      58         /// <param name="commandParameters">Array of SqlParameters to be assigned values</param>
      59         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values</param>
      60         private static void AssignParameterValues(SqlParameter[] commandParameters, DataRow dataRow)
      61         {
      62             if ((commandParameters == null) || (dataRow == null))
      63             {
      64                 // Do nothing if we get no data
      65                 return;
      66             }
      67 
      68             int i = 0;
      69             // Set the parameters values
      70             foreach (SqlParameter commandParameter in commandParameters)
      71             {
      72                 // Check the parameter name
      73                 if (commandParameter.ParameterName == null ||
      74                     commandParameter.ParameterName.Length <= 1)
      75                     throw new Exception(
      76                         string.Format(
      77                             "Please provide a valid parameter name on the parameter #{0}, the ParameterName property has the following value: '{1}'.",
      78                             i, commandParameter.ParameterName));
      79                 if (dataRow.Table.Columns.IndexOf(commandParameter.ParameterName.Substring(1)) != -1)
      80                     commandParameter.Value = dataRow[commandParameter.ParameterName.Substring(1)];
      81                 i++;
      82             }
      83         }
      84 
      85         /// <summary>
      86         /// This method assigns an array of values to an array of SqlParameters
      87         /// </summary>
      88         /// <param name="commandParameters">Array of SqlParameters to be assigned values</param>
      89         /// <param name="parameterValues">Array of objects holding the values to be assigned</param>
      90         private static void AssignParameterValues(SqlParameter[] commandParameters, object[] parameterValues)
      91         {
      92             if ((commandParameters == null) || (parameterValues == null))
      93             {
      94                 // Do nothing if we get no data
      95                 return;
      96             }
      97 
      98             // We must have the same number of values as we pave parameters to put them in
      99             if (commandParameters.Length != parameterValues.Length)
     100             {
     101                 throw new ArgumentException("Parameter count does not match Parameter Value count.");
     102             }
     103 
     104             // Iterate through the SqlParameters, assigning the values from the corresponding position in the 
     105             // value array
     106             for (int i = 0, j = commandParameters.Length; i < j; i++)
     107             {
     108                 // If the current array value derives from IDbDataParameter, then assign its Value property
     109                 if (parameterValues[i] is IDbDataParameter)
     110                 {
     111                     IDbDataParameter paramInstance = (IDbDataParameter)parameterValues[i];
     112                     if (paramInstance.Value == null)
     113                     {
     114                         commandParameters[i].Value = DBNull.Value;
     115                     }
     116                     else
     117                     {
     118                         commandParameters[i].Value = paramInstance.Value;
     119                     }
     120                 }
     121                 else if (parameterValues[i] == null)
     122                 {
     123                     commandParameters[i].Value = DBNull.Value;
     124                 }
     125                 else
     126                 {
     127                     commandParameters[i].Value = parameterValues[i];
     128                 }
     129             }
     130         }
     131 
     132         /// <summary>
     133         /// This method opens (if necessary) and assigns a connection, transaction, command type and parameters 
     134         /// to the provided command
     135         /// </summary>
     136         /// <param name="command">The SqlCommand to be prepared</param>
     137         /// <param name="connection">A valid SqlConnection, on which to execute this command</param>
     138         /// <param name="transaction">A valid SqlTransaction, or 'null'</param>
     139         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     140         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     141         /// <param name="commandParameters">An array of SqlParameters to be associated with the command or 'null' if no parameters are required</param>
     142         /// <param name="mustCloseConnection"><c>true</c> if the connection was opened by the method, otherwose is false.</param>
     143         private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction,
     144             CommandType commandType, string commandText, SqlParameter[] commandParameters, out bool mustCloseConnection)
     145         {
     146             if (command == null) throw new ArgumentNullException("command");
     147             if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");
     148 
     149             // If the provided connection is not open, we will open it
     150             if (connection.State != ConnectionState.Open)
     151             {
     152                 mustCloseConnection = true;
     153                 connection.Open();
     154             }
     155             else
     156             {
     157                 mustCloseConnection = false;
     158             }
     159 
     160             // Associate the connection with the command
     161             command.Connection = connection;
     162 
     163             // Set the command text (stored procedure name or SQL statement)
     164             command.CommandText = commandText;
     165 
     166             // If we were provided a transaction, assign it
     167             if (transaction != null)
     168             {
     169                 if (transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
     170                 command.Transaction = transaction;
     171             }
     172 
     173             // Set the command type
     174             command.CommandType = commandType;
     175 
     176             // Attach the command parameters if they are provided
     177             if (commandParameters != null)
     178             {
     179                 AttachParameters(command, commandParameters);
     180             }
     181             return;
     182         }
     183 
     184         #endregion private utility methods & constructors
     185 
     186         #region ExecuteNonQuery
     187 
     188         /// <summary>
     189         /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the database specified in 
     190         /// the connection string
     191         /// </summary>
     192         /// <remarks>
     193         /// e.g.:  
     194         ///  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders");
     195         /// </remarks>
     196         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
     197         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     198         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     199         /// <returns>An int representing the number of rows affected by the command</returns>
     200         public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText)
     201         {
     202             // Pass through the call providing null for the set of SqlParameters
     203             return ExecuteNonQuery(connectionString, commandType, commandText, (SqlParameter[])null);
     204         }
     205 
     206         /// <summary>
     207         /// Execute a SqlCommand (that returns no resultset) against the database specified in the connection string 
     208         /// using the provided parameters
     209         /// </summary>
     210         /// <remarks>
     211         /// e.g.:  
     212         ///  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
     213         /// </remarks>
     214         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
     215         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     216         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     217         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
     218         /// <returns>An int representing the number of rows affected by the command</returns>
     219         public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
     220         {
     221             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
     222 
     223             // Create & open a SqlConnection, and dispose of it after we are done
     224             using (SqlConnection connection = new SqlConnection(connectionString))
     225             {
     226                 connection.Open();
     227 
     228                 // Call the overload that takes a connection in place of the connection string
     229                 return ExecuteNonQuery(connection, commandType, commandText, commandParameters);
     230             }
     231         }
     232 
     233         /// <summary>
     234         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the database specified in 
     235         /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
     236         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
     237         /// </summary>
     238         /// <remarks>
     239         /// This method provides no access to output parameters or the stored procedure's return value parameter.
     240         /// 
     241         /// e.g.:  
     242         ///  int result = ExecuteNonQuery(connString, "PublishOrders", 24, 36);
     243         /// </remarks>
     244         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
     245         /// <param name="spName">The name of the stored prcedure</param>
     246         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
     247         /// <returns>An int representing the number of rows affected by the command</returns>
     248         public static int ExecuteNonQuery(string connectionString, string spName, params object[] parameterValues)
     249         {
     250             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
     251             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
     252 
     253             // If we receive parameter values, we need to figure out where they go
     254             if ((parameterValues != null) && (parameterValues.Length > 0))
     255             {
     256                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
     257                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
     258 
     259                 // Assign the provided values to these parameters based on parameter order
     260                 AssignParameterValues(commandParameters, parameterValues);
     261 
     262                 // Call the overload that takes an array of SqlParameters
     263                 return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters);
     264             }
     265             else
     266             {
     267                 // Otherwise we can just call the SP without params
     268                 return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName);
     269             }
     270         }
     271 
     272         /// <summary>
     273         /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the provided SqlConnection. 
     274         /// </summary>
     275         /// <remarks>
     276         /// e.g.:  
     277         ///  int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders");
     278         /// </remarks>
     279         /// <param name="connection">A valid SqlConnection</param>
     280         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     281         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     282         /// <returns>An int representing the number of rows affected by the command</returns>
     283         public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText)
     284         {
     285             // Pass through the call providing null for the set of SqlParameters
     286             return ExecuteNonQuery(connection, commandType, commandText, (SqlParameter[])null);
     287         }
     288 
     289         /// <summary>
     290         /// Execute a SqlCommand (that returns no resultset) against the specified SqlConnection 
     291         /// using the provided parameters.
     292         /// </summary>
     293         /// <remarks>
     294         /// e.g.:  
     295         ///  int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
     296         /// </remarks>
     297         /// <param name="connection">A valid SqlConnection</param>
     298         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     299         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     300         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
     301         /// <returns>An int representing the number of rows affected by the command</returns>
     302         public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
     303         {
     304             if (connection == null) throw new ArgumentNullException("connection");
     305 
     306             // Create a command and prepare it for execution
     307             SqlCommand cmd = new SqlCommand();
     308             bool mustCloseConnection = false;
     309             PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);
     310 
     311             // Finally, execute the command
     312             int retval = cmd.ExecuteNonQuery();
     313 
     314             // Detach the SqlParameters from the command object, so they can be used again
     315             cmd.Parameters.Clear();
     316             if (mustCloseConnection)
     317                 connection.Close();
     318             return retval;
     319         }
     320 
     321         /// <summary>
     322         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified SqlConnection 
     323         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
     324         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
     325         /// </summary>
     326         /// <remarks>
     327         /// This method provides no access to output parameters or the stored procedure's return value parameter.
     328         /// 
     329         /// e.g.:  
     330         ///  int result = ExecuteNonQuery(conn, "PublishOrders", 24, 36);
     331         /// </remarks>
     332         /// <param name="connection">A valid SqlConnection</param>
     333         /// <param name="spName">The name of the stored procedure</param>
     334         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
     335         /// <returns>An int representing the number of rows affected by the command</returns>
     336         public static int ExecuteNonQuery(SqlConnection connection, string spName, params object[] parameterValues)
     337         {
     338             if (connection == null) throw new ArgumentNullException("connection");
     339             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
     340 
     341             // If we receive parameter values, we need to figure out where they go
     342             if ((parameterValues != null) && (parameterValues.Length > 0))
     343             {
     344                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
     345                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
     346 
     347                 // Assign the provided values to these parameters based on parameter order
     348                 AssignParameterValues(commandParameters, parameterValues);
     349 
     350                 // Call the overload that takes an array of SqlParameters
     351                 return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName, commandParameters);
     352             }
     353             else
     354             {
     355                 // Otherwise we can just call the SP without params
     356                 return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName);
     357             }
     358         }
     359 
     360         /// <summary>
     361         /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the provided SqlTransaction. 
     362         /// </summary>
     363         /// <remarks>
     364         /// e.g.:  
     365         ///  int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "PublishOrders");
     366         /// </remarks>
     367         /// <param name="transaction">A valid SqlTransaction</param>
     368         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     369         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     370         /// <returns>An int representing the number of rows affected by the command</returns>
     371         public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText)
     372         {
     373             // Pass through the call providing null for the set of SqlParameters
     374             return ExecuteNonQuery(transaction, commandType, commandText, (SqlParameter[])null);
     375         }
     376 
     377         /// <summary>
     378         /// Execute a SqlCommand (that returns no resultset) against the specified SqlTransaction
     379         /// using the provided parameters.
     380         /// </summary>
     381         /// <remarks>
     382         /// e.g.:  
     383         ///  int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
     384         /// </remarks>
     385         /// <param name="transaction">A valid SqlTransaction</param>
     386         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     387         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     388         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
     389         /// <returns>An int representing the number of rows affected by the command</returns>
     390         public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
     391         {
     392             if (transaction == null) throw new ArgumentNullException("transaction");
     393             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
     394 
     395             // Create a command and prepare it for execution
     396             SqlCommand cmd = new SqlCommand();
     397             bool mustCloseConnection = false;
     398             PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
     399 
     400             // Finally, execute the command
     401             int retval = cmd.ExecuteNonQuery();
     402 
     403             // Detach the SqlParameters from the command object, so they can be used again
     404             cmd.Parameters.Clear();
     405             return retval;
     406         }
     407 
     408         /// <summary>
     409         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified 
     410         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
     411         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
     412         /// </summary>
     413         /// <remarks>
     414         /// This method provides no access to output parameters or the stored procedure's return value parameter.
     415         /// 
     416         /// e.g.:  
     417         ///  int result = ExecuteNonQuery(conn, trans, "PublishOrders", 24, 36);
     418         /// </remarks>
     419         /// <param name="transaction">A valid SqlTransaction</param>
     420         /// <param name="spName">The name of the stored procedure</param>
     421         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
     422         /// <returns>An int representing the number of rows affected by the command</returns>
     423         public static int ExecuteNonQuery(SqlTransaction transaction, string spName, params object[] parameterValues)
     424         {
     425             if (transaction == null) throw new ArgumentNullException("transaction");
     426             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
     427             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
     428 
     429             // If we receive parameter values, we need to figure out where they go
     430             if ((parameterValues != null) && (parameterValues.Length > 0))
     431             {
     432                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
     433                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
     434 
     435                 // Assign the provided values to these parameters based on parameter order
     436                 AssignParameterValues(commandParameters, parameterValues);
     437 
     438                 // Call the overload that takes an array of SqlParameters
     439                 return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName, commandParameters);
     440             }
     441             else
     442             {
     443                 // Otherwise we can just call the SP without params
     444                 return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName);
     445             }
     446         }
     447 
     448         #endregion ExecuteNonQuery
     449 
     450         #region ExecuteDataset
     451 
     452         /// <summary>
     453         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in 
     454         /// the connection string. 
     455         /// </summary>
     456         /// <remarks>
     457         /// e.g.:  
     458         ///  DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders");
     459         /// </remarks>
     460         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
     461         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     462         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     463         /// <returns>A dataset containing the resultset generated by the command</returns>
     464         public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText)
     465         {
     466             // Pass through the call providing null for the set of SqlParameters
     467             return ExecuteDataset(connectionString, commandType, commandText, (SqlParameter[])null);
     468         }
     469 
     470         /// <summary>
     471         /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string 
     472         /// using the provided parameters.
     473         /// </summary>
     474         /// <remarks>
     475         /// e.g.:  
     476         ///  DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
     477         /// </remarks>
     478         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
     479         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     480         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     481         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
     482         /// <returns>A dataset containing the resultset generated by the command</returns>
     483         public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
     484         {
     485             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
     486 
     487             // Create & open a SqlConnection, and dispose of it after we are done
     488             using (SqlConnection connection = new SqlConnection(connectionString))
     489             {
     490                 connection.Open();
     491 
     492                 // Call the overload that takes a connection in place of the connection string
     493                 return ExecuteDataset(connection, commandType, commandText, commandParameters);
     494             }
     495         }
     496 
     497         /// <summary>
     498         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 
     499         /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
     500         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
     501         /// </summary>
     502         /// <remarks>
     503         /// This method provides no access to output parameters or the stored procedure's return value parameter.
     504         /// 
     505         /// e.g.:  
     506         ///  DataSet ds = ExecuteDataset(connString, "GetOrders", 24, 36);
     507         /// </remarks>
     508         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
     509         /// <param name="spName">The name of the stored procedure</param>
     510         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
     511         /// <returns>A dataset containing the resultset generated by the command</returns>
     512         public static DataSet ExecuteDataset(string connectionString, string spName, params object[] parameterValues)
     513         {
     514             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
     515             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
     516 
     517             // If we receive parameter values, we need to figure out where they go
     518             if ((parameterValues != null) && (parameterValues.Length > 0))
     519             {
     520                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
     521                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
     522 
     523                 // Assign the provided values to these parameters based on parameter order
     524                 AssignParameterValues(commandParameters, parameterValues);
     525 
     526                 // Call the overload that takes an array of SqlParameters
     527                 return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName, commandParameters);
     528             }
     529             else
     530             {
     531                 // Otherwise we can just call the SP without params
     532                 return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName);
     533             }
     534         }
     535 
     536         /// <summary>
     537         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. 
     538         /// </summary>
     539         /// <remarks>
     540         /// e.g.:  
     541         ///  DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders");
     542         /// </remarks>
     543         /// <param name="connection">A valid SqlConnection</param>
     544         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     545         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     546         /// <returns>A dataset containing the resultset generated by the command</returns>
     547         public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText)
     548         {
     549             // Pass through the call providing null for the set of SqlParameters
     550             return ExecuteDataset(connection, commandType, commandText, (SqlParameter[])null);
     551         }
     552 
     553         /// <summary>
     554         /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 
     555         /// using the provided parameters.
     556         /// </summary>
     557         /// <remarks>
     558         /// e.g.:  
     559         ///  DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
     560         /// </remarks>
     561         /// <param name="connection">A valid SqlConnection</param>
     562         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     563         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     564         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
     565         /// <returns>A dataset containing the resultset generated by the command</returns>
     566         public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
     567         {
     568             if (connection == null) throw new ArgumentNullException("connection");
     569 
     570             // Create a command and prepare it for execution
     571             SqlCommand cmd = new SqlCommand();
     572             bool mustCloseConnection = false;
     573             PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);
     574 
     575             // Create the DataAdapter & DataSet
     576             using (SqlDataAdapter da = new SqlDataAdapter(cmd))
     577             {
     578                 DataSet ds = new DataSet();
     579 
     580                 // Fill the DataSet using default values for DataTable names, etc
     581                 da.Fill(ds);
     582 
     583                 // Detach the SqlParameters from the command object, so they can be used again
     584                 cmd.Parameters.Clear();
     585 
     586                 if (mustCloseConnection)
     587                     connection.Close();
     588 
     589                 // Return the dataset
     590                 return ds;
     591             }
     592         }
     593 
     594         /// <summary>
     595         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
     596         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
     597         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
     598         /// </summary>
     599         /// <remarks>
     600         /// This method provides no access to output parameters or the stored procedure's return value parameter.
     601         /// 
     602         /// e.g.:  
     603         ///  DataSet ds = ExecuteDataset(conn, "GetOrders", 24, 36);
     604         /// </remarks>
     605         /// <param name="connection">A valid SqlConnection</param>
     606         /// <param name="spName">The name of the stored procedure</param>
     607         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
     608         /// <returns>A dataset containing the resultset generated by the command</returns>
     609         public static DataSet ExecuteDataset(SqlConnection connection, string spName, params object[] parameterValues)
     610         {
     611             if (connection == null) throw new ArgumentNullException("connection");
     612             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
     613 
     614             // If we receive parameter values, we need to figure out where they go
     615             if ((parameterValues != null) && (parameterValues.Length > 0))
     616             {
     617                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
     618                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
     619 
     620                 // Assign the provided values to these parameters based on parameter order
     621                 AssignParameterValues(commandParameters, parameterValues);
     622 
     623                 // Call the overload that takes an array of SqlParameters
     624                 return ExecuteDataset(connection, CommandType.StoredProcedure, spName, commandParameters);
     625             }
     626             else
     627             {
     628                 // Otherwise we can just call the SP without params
     629                 return ExecuteDataset(connection, CommandType.StoredProcedure, spName);
     630             }
     631         }
     632 
     633         /// <summary>
     634         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. 
     635         /// </summary>
     636         /// <remarks>
     637         /// e.g.:  
     638         ///  DataSet ds = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders");
     639         /// </remarks>
     640         /// <param name="transaction">A valid SqlTransaction</param>
     641         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     642         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     643         /// <returns>A dataset containing the resultset generated by the command</returns>
     644         public static DataSet ExecuteDataset(SqlTransaction transaction, CommandType commandType, string commandText)
     645         {
     646             // Pass through the call providing null for the set of SqlParameters
     647             return ExecuteDataset(transaction, commandType, commandText, (SqlParameter[])null);
     648         }
     649 
     650         /// <summary>
     651         /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction
     652         /// using the provided parameters.
     653         /// </summary>
     654         /// <remarks>
     655         /// e.g.:  
     656         ///  DataSet ds = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
     657         /// </remarks>
     658         /// <param name="transaction">A valid SqlTransaction</param>
     659         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     660         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     661         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
     662         /// <returns>A dataset containing the resultset generated by the command</returns>
     663         public static DataSet ExecuteDataset(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
     664         {
     665             if (transaction == null) throw new ArgumentNullException("transaction");
     666             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
     667 
     668             // Create a command and prepare it for execution
     669             SqlCommand cmd = new SqlCommand();
     670             bool mustCloseConnection = false;
     671             PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
     672 
     673             // Create the DataAdapter & DataSet
     674             using (SqlDataAdapter da = new SqlDataAdapter(cmd))
     675             {
     676                 DataSet ds = new DataSet();
     677 
     678                 // Fill the DataSet using default values for DataTable names, etc
     679                 da.Fill(ds);
     680 
     681                 // Detach the SqlParameters from the command object, so they can be used again
     682                 cmd.Parameters.Clear();
     683 
     684                 // Return the dataset
     685                 return ds;
     686             }
     687         }
     688 
     689         /// <summary>
     690         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified 
     691         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
     692         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
     693         /// </summary>
     694         /// <remarks>
     695         /// This method provides no access to output parameters or the stored procedure's return value parameter.
     696         /// 
     697         /// e.g.:  
     698         ///  DataSet ds = ExecuteDataset(trans, "GetOrders", 24, 36);
     699         /// </remarks>
     700         /// <param name="transaction">A valid SqlTransaction</param>
     701         /// <param name="spName">The name of the stored procedure</param>
     702         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
     703         /// <returns>A dataset containing the resultset generated by the command</returns>
     704         public static DataSet ExecuteDataset(SqlTransaction transaction, string spName, params object[] parameterValues)
     705         {
     706             if (transaction == null) throw new ArgumentNullException("transaction");
     707             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
     708             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
     709 
     710             // If we receive parameter values, we need to figure out where they go
     711             if ((parameterValues != null) && (parameterValues.Length > 0))
     712             {
     713                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
     714                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
     715 
     716                 // Assign the provided values to these parameters based on parameter order
     717                 AssignParameterValues(commandParameters, parameterValues);
     718 
     719                 // Call the overload that takes an array of SqlParameters
     720                 return ExecuteDataset(transaction, CommandType.StoredProcedure, spName, commandParameters);
     721             }
     722             else
     723             {
     724                 // Otherwise we can just call the SP without params
     725                 return ExecuteDataset(transaction, CommandType.StoredProcedure, spName);
     726             }
     727         }
     728 
     729         #endregion ExecuteDataset
     730 
     731         #region ExecuteReader
     732 
     733         /// <summary>
     734         /// This enum is used to indicate whether the connection was provided by the caller, or created by SqlHelper, so that
     735         /// we can set the appropriate CommandBehavior when calling ExecuteReader()
     736         /// </summary>
     737         private enum SqlConnectionOwnership
     738         {
     739             /// <summary>Connection is owned and managed by SqlHelper</summary>
     740             Internal,
     741             /// <summary>Connection is owned and managed by the caller</summary>
     742             External
     743         }
     744 
     745         /// <summary>
     746         /// Create and prepare a SqlCommand, and call ExecuteReader with the appropriate CommandBehavior.
     747         /// </summary>
     748         /// <remarks>
     749         /// If we created and opened the connection, we want the connection to be closed when the DataReader is closed.
     750         /// 
     751         /// If the caller provided the connection, we want to leave it to them to manage.
     752         /// </remarks>
     753         /// <param name="connection">A valid SqlConnection, on which to execute this command</param>
     754         /// <param name="transaction">A valid SqlTransaction, or 'null'</param>
     755         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     756         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     757         /// <param name="commandParameters">An array of SqlParameters to be associated with the command or 'null' if no parameters are required</param>
     758         /// <param name="connectionOwnership">Indicates whether the connection parameter was provided by the caller, or created by SqlHelper</param>
     759         /// <returns>SqlDataReader containing the results of the command</returns>
     760         private static SqlDataReader ExecuteReader(SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, SqlConnectionOwnership connectionOwnership)
     761         {
     762             if (connection == null) throw new ArgumentNullException("connection");
     763 
     764             bool mustCloseConnection = false;
     765             // Create a command and prepare it for execution
     766             SqlCommand cmd = new SqlCommand();
     767             try
     768             {
     769                 PrepareCommand(cmd, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
     770 
     771                 // Create a reader
     772                 SqlDataReader dataReader;
     773 
     774                 // Call ExecuteReader with the appropriate CommandBehavior
     775                 if (connectionOwnership == SqlConnectionOwnership.External)
     776                 {
     777                     dataReader = cmd.ExecuteReader();
     778                 }
     779                 else
     780                 {
     781                     dataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
     782                 }
     783 
     784                 // Detach the SqlParameters from the command object, so they can be used again.
     785                 // HACK: There is a problem here, the output parameter values are fletched 
     786                 // when the reader is closed, so if the parameters are detached from the command
     787                 // then the SqlReader can磘 set its values. 
     788                 // When this happen, the parameters can磘 be used again in other command.
     789                 bool canClear = true;
     790                 foreach (SqlParameter commandParameter in cmd.Parameters)
     791                 {
     792                     if (commandParameter.Direction != ParameterDirection.Input)
     793                         canClear = false;
     794                 }
     795 
     796                 if (canClear)
     797                 {
     798                     cmd.Parameters.Clear();
     799                 }
     800 
     801                 return dataReader;
     802             }
     803             catch
     804             {
     805                 if (mustCloseConnection)
     806                     connection.Close();
     807                 throw;
     808             }
     809         }
     810 
     811         /// <summary>
     812         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in 
     813         /// the connection string. 
     814         /// </summary>
     815         /// <remarks>
     816         /// e.g.:  
     817         ///  SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders");
     818         /// </remarks>
     819         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
     820         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     821         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     822         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
     823         public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText)
     824         {
     825             // Pass through the call providing null for the set of SqlParameters
     826             return ExecuteReader(connectionString, commandType, commandText, (SqlParameter[])null);
     827         }
     828 
     829         /// <summary>
     830         /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string 
     831         /// using the provided parameters.
     832         /// </summary>
     833         /// <remarks>
     834         /// e.g.:  
     835         ///  SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
     836         /// </remarks>
     837         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
     838         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     839         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     840         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
     841         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
     842         public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
     843         {
     844             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
     845             SqlConnection connection = null;
     846             try
     847             {
     848                 connection = new SqlConnection(connectionString);
     849                 connection.Open();
     850 
     851                 // Call the private overload that takes an internally owned connection in place of the connection string
     852                 return ExecuteReader(connection, null, commandType, commandText, commandParameters, SqlConnectionOwnership.Internal);
     853             }
     854             catch
     855             {
     856                 // If we fail to return the SqlDatReader, we need to close the connection ourselves
     857                 if (connection != null) connection.Close();
     858                 throw;
     859             }
     860 
     861         }
     862 
     863         /// <summary>
     864         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 
     865         /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
     866         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
     867         /// </summary>
     868         /// <remarks>
     869         /// This method provides no access to output parameters or the stored procedure's return value parameter.
     870         /// 
     871         /// e.g.:  
     872         ///  SqlDataReader dr = ExecuteReader(connString, "GetOrders", 24, 36);
     873         /// </remarks>
     874         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
     875         /// <param name="spName">The name of the stored procedure</param>
     876         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
     877         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
     878         public static SqlDataReader ExecuteReader(string connectionString, string spName, params object[] parameterValues)
     879         {
     880             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
     881             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
     882 
     883             // If we receive parameter values, we need to figure out where they go
     884             if ((parameterValues != null) && (parameterValues.Length > 0))
     885             {
     886                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
     887 
     888                 AssignParameterValues(commandParameters, parameterValues);
     889 
     890                 return ExecuteReader(connectionString, CommandType.StoredProcedure, spName, commandParameters);
     891             }
     892             else
     893             {
     894                 // Otherwise we can just call the SP without params
     895                 return ExecuteReader(connectionString, CommandType.StoredProcedure, spName);
     896             }
     897         }
     898 
     899         /// <summary>
     900         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. 
     901         /// </summary>
     902         /// <remarks>
     903         /// e.g.:  
     904         ///  SqlDataReader dr = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders");
     905         /// </remarks>
     906         /// <param name="connection">A valid SqlConnection</param>
     907         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     908         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     909         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
     910         public static SqlDataReader ExecuteReader(SqlConnection connection, CommandType commandType, string commandText)
     911         {
     912             // Pass through the call providing null for the set of SqlParameters
     913             return ExecuteReader(connection, commandType, commandText, (SqlParameter[])null);
     914         }
     915 
     916         /// <summary>
     917         /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 
     918         /// using the provided parameters.
     919         /// </summary>
     920         /// <remarks>
     921         /// e.g.:  
     922         ///  SqlDataReader dr = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
     923         /// </remarks>
     924         /// <param name="connection">A valid SqlConnection</param>
     925         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     926         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     927         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
     928         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
     929         public static SqlDataReader ExecuteReader(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
     930         {
     931             // Pass through the call to the private overload using a null transaction value and an externally owned connection
     932             return ExecuteReader(connection, (SqlTransaction)null, commandType, commandText, commandParameters, SqlConnectionOwnership.External);
     933         }
     934 
     935         /// <summary>
     936         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
     937         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
     938         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
     939         /// </summary>
     940         /// <remarks>
     941         /// This method provides no access to output parameters or the stored procedure's return value parameter.
     942         /// 
     943         /// e.g.:  
     944         ///  SqlDataReader dr = ExecuteReader(conn, "GetOrders", 24, 36);
     945         /// </remarks>
     946         /// <param name="connection">A valid SqlConnection</param>
     947         /// <param name="spName">The name of the stored procedure</param>
     948         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
     949         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
     950         public static SqlDataReader ExecuteReader(SqlConnection connection, string spName, params object[] parameterValues)
     951         {
     952             if (connection == null) throw new ArgumentNullException("connection");
     953             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
     954 
     955             // If we receive parameter values, we need to figure out where they go
     956             if ((parameterValues != null) && (parameterValues.Length > 0))
     957             {
     958                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
     959 
     960                 AssignParameterValues(commandParameters, parameterValues);
     961 
     962                 return ExecuteReader(connection, CommandType.StoredProcedure, spName, commandParameters);
     963             }
     964             else
     965             {
     966                 // Otherwise we can just call the SP without params
     967                 return ExecuteReader(connection, CommandType.StoredProcedure, spName);
     968             }
     969         }
     970 
     971         /// <summary>
     972         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. 
     973         /// </summary>
     974         /// <remarks>
     975         /// e.g.:  
     976         ///  SqlDataReader dr = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders");
     977         /// </remarks>
     978         /// <param name="transaction">A valid SqlTransaction</param>
     979         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     980         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     981         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
     982         public static SqlDataReader ExecuteReader(SqlTransaction transaction, CommandType commandType, string commandText)
     983         {
     984             // Pass through the call providing null for the set of SqlParameters
     985             return ExecuteReader(transaction, commandType, commandText, (SqlParameter[])null);
     986         }
     987 
     988         /// <summary>
     989         /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction
     990         /// using the provided parameters.
     991         /// </summary>
     992         /// <remarks>
     993         /// e.g.:  
     994         ///   SqlDataReader dr = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
     995         /// </remarks>
     996         /// <param name="transaction">A valid SqlTransaction</param>
     997         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
     998         /// <param name="commandText">The stored procedure name or T-SQL command</param>
     999         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
    1000         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
    1001         public static SqlDataReader ExecuteReader(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
    1002         {
    1003             if (transaction == null) throw new ArgumentNullException("transaction");
    1004             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
    1005 
    1006             // Pass through to private overload, indicating that the connection is owned by the caller
    1007             return ExecuteReader(transaction.Connection, transaction, commandType, commandText, commandParameters, SqlConnectionOwnership.External);
    1008         }
    1009 
    1010         /// <summary>
    1011         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified
    1012         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
    1013         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    1014         /// </summary>
    1015         /// <remarks>
    1016         /// This method provides no access to output parameters or the stored procedure's return value parameter.
    1017         /// 
    1018         /// e.g.:  
    1019         ///  SqlDataReader dr = ExecuteReader(trans, "GetOrders", 24, 36);
    1020         /// </remarks>
    1021         /// <param name="transaction">A valid SqlTransaction</param>
    1022         /// <param name="spName">The name of the stored procedure</param>
    1023         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
    1024         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
    1025         public static SqlDataReader ExecuteReader(SqlTransaction transaction, string spName, params object[] parameterValues)
    1026         {
    1027             if (transaction == null) throw new ArgumentNullException("transaction");
    1028             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
    1029             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    1030 
    1031             // If we receive parameter values, we need to figure out where they go
    1032             if ((parameterValues != null) && (parameterValues.Length > 0))
    1033             {
    1034                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
    1035 
    1036                 AssignParameterValues(commandParameters, parameterValues);
    1037 
    1038                 return ExecuteReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
    1039             }
    1040             else
    1041             {
    1042                 // Otherwise we can just call the SP without params
    1043                 return ExecuteReader(transaction, CommandType.StoredProcedure, spName);
    1044             }
    1045         }
    1046 
    1047         #endregion ExecuteReader
    1048 
    1049         #region ExecuteScalar
    1050 
    1051         /// <summary>
    1052         /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the database specified in 
    1053         /// the connection string. 
    1054         /// </summary>
    1055         /// <remarks>
    1056         /// e.g.:  
    1057         ///  int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount");
    1058         /// </remarks>
    1059         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    1060         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1061         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    1062         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
    1063         public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText)
    1064         {
    1065             // Pass through the call providing null for the set of SqlParameters
    1066             return ExecuteScalar(connectionString, commandType, commandText, (SqlParameter[])null);
    1067         }
    1068 
    1069         /// <summary>
    1070         /// Execute a SqlCommand (that returns a 1x1 resultset) against the database specified in the connection string 
    1071         /// using the provided parameters.
    1072         /// </summary>
    1073         /// <remarks>
    1074         /// e.g.:  
    1075         ///  int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));
    1076         /// </remarks>
    1077         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    1078         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1079         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    1080         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
    1081         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
    1082         public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
    1083         {
    1084             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
    1085             // Create & open a SqlConnection, and dispose of it after we are done
    1086             using (SqlConnection connection = new SqlConnection(connectionString))
    1087             {
    1088                 connection.Open();
    1089 
    1090                 // Call the overload that takes a connection in place of the connection string
    1091                 return ExecuteScalar(connection, commandType, commandText, commandParameters);
    1092             }
    1093         }
    1094 
    1095         /// <summary>
    1096         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the database specified in 
    1097         /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
    1098         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    1099         /// </summary>
    1100         /// <remarks>
    1101         /// This method provides no access to output parameters or the stored procedure's return value parameter.
    1102         /// 
    1103         /// e.g.:  
    1104         ///  int orderCount = (int)ExecuteScalar(connString, "GetOrderCount", 24, 36);
    1105         /// </remarks>
    1106         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    1107         /// <param name="spName">The name of the stored procedure</param>
    1108         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
    1109         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
    1110         public static object ExecuteScalar(string connectionString, string spName, params object[] parameterValues)
    1111         {
    1112             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
    1113             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    1114 
    1115             // If we receive parameter values, we need to figure out where they go
    1116             if ((parameterValues != null) && (parameterValues.Length > 0))
    1117             {
    1118                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    1119                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
    1120 
    1121                 // Assign the provided values to these parameters based on parameter order
    1122                 AssignParameterValues(commandParameters, parameterValues);
    1123 
    1124                 // Call the overload that takes an array of SqlParameters
    1125                 return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName, commandParameters);
    1126             }
    1127             else
    1128             {
    1129                 // Otherwise we can just call the SP without params
    1130                 return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName);
    1131             }
    1132         }
    1133 
    1134         /// <summary>
    1135         /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the provided SqlConnection. 
    1136         /// </summary>
    1137         /// <remarks>
    1138         /// e.g.:  
    1139         ///  int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount");
    1140         /// </remarks>
    1141         /// <param name="connection">A valid SqlConnection</param>
    1142         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1143         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    1144         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
    1145         public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText)
    1146         {
    1147             // Pass through the call providing null for the set of SqlParameters
    1148             return ExecuteScalar(connection, commandType, commandText, (SqlParameter[])null);
    1149         }
    1150 
    1151         /// <summary>
    1152         /// Execute a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection 
    1153         /// using the provided parameters.
    1154         /// </summary>
    1155         /// <remarks>
    1156         /// e.g.:  
    1157         ///  int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));
    1158         /// </remarks>
    1159         /// <param name="connection">A valid SqlConnection</param>
    1160         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1161         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    1162         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
    1163         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
    1164         public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
    1165         {
    1166             if (connection == null) throw new ArgumentNullException("connection");
    1167 
    1168             // Create a command and prepare it for execution
    1169             SqlCommand cmd = new SqlCommand();
    1170 
    1171             bool mustCloseConnection = false;
    1172             PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);
    1173 
    1174             // Execute the command & return the results
    1175             object retval = cmd.ExecuteScalar();
    1176 
    1177             // Detach the SqlParameters from the command object, so they can be used again
    1178             cmd.Parameters.Clear();
    1179 
    1180             if (mustCloseConnection)
    1181                 connection.Close();
    1182 
    1183             return retval;
    1184         }
    1185 
    1186         /// <summary>
    1187         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection 
    1188         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
    1189         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    1190         /// </summary>
    1191         /// <remarks>
    1192         /// This method provides no access to output parameters or the stored procedure's return value parameter.
    1193         /// 
    1194         /// e.g.:  
    1195         ///  int orderCount = (int)ExecuteScalar(conn, "GetOrderCount", 24, 36);
    1196         /// </remarks>
    1197         /// <param name="connection">A valid SqlConnection</param>
    1198         /// <param name="spName">The name of the stored procedure</param>
    1199         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
    1200         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
    1201         public static object ExecuteScalar(SqlConnection connection, string spName, params object[] parameterValues)
    1202         {
    1203             if (connection == null) throw new ArgumentNullException("connection");
    1204             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    1205 
    1206             // If we receive parameter values, we need to figure out where they go
    1207             if ((parameterValues != null) && (parameterValues.Length > 0))
    1208             {
    1209                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    1210                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
    1211 
    1212                 // Assign the provided values to these parameters based on parameter order
    1213                 AssignParameterValues(commandParameters, parameterValues);
    1214 
    1215                 // Call the overload that takes an array of SqlParameters
    1216                 return ExecuteScalar(connection, CommandType.StoredProcedure, spName, commandParameters);
    1217             }
    1218             else
    1219             {
    1220                 // Otherwise we can just call the SP without params
    1221                 return ExecuteScalar(connection, CommandType.StoredProcedure, spName);
    1222             }
    1223         }
    1224 
    1225         /// <summary>
    1226         /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the provided SqlTransaction. 
    1227         /// </summary>
    1228         /// <remarks>
    1229         /// e.g.:  
    1230         ///  int orderCount = (int)ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount");
    1231         /// </remarks>
    1232         /// <param name="transaction">A valid SqlTransaction</param>
    1233         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1234         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    1235         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
    1236         public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText)
    1237         {
    1238             // Pass through the call providing null for the set of SqlParameters
    1239             return ExecuteScalar(transaction, commandType, commandText, (SqlParameter[])null);
    1240         }
    1241 
    1242         /// <summary>
    1243         /// Execute a SqlCommand (that returns a 1x1 resultset) against the specified SqlTransaction
    1244         /// using the provided parameters.
    1245         /// </summary>
    1246         /// <remarks>
    1247         /// e.g.:  
    1248         ///  int orderCount = (int)ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));
    1249         /// </remarks>
    1250         /// <param name="transaction">A valid SqlTransaction</param>
    1251         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1252         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    1253         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
    1254         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
    1255         public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
    1256         {
    1257             if (transaction == null) throw new ArgumentNullException("transaction");
    1258             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
    1259 
    1260             // Create a command and prepare it for execution
    1261             SqlCommand cmd = new SqlCommand();
    1262             bool mustCloseConnection = false;
    1263             PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
    1264 
    1265             // Execute the command & return the results
    1266             object retval = cmd.ExecuteScalar();
    1267 
    1268             // Detach the SqlParameters from the command object, so they can be used again
    1269             cmd.Parameters.Clear();
    1270             return retval;
    1271         }
    1272 
    1273         /// <summary>
    1274         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified
    1275         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
    1276         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    1277         /// </summary>
    1278         /// <remarks>
    1279         /// This method provides no access to output parameters or the stored procedure's return value parameter.
    1280         /// 
    1281         /// e.g.:  
    1282         ///  int orderCount = (int)ExecuteScalar(trans, "GetOrderCount", 24, 36);
    1283         /// </remarks>
    1284         /// <param name="transaction">A valid SqlTransaction</param>
    1285         /// <param name="spName">The name of the stored procedure</param>
    1286         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
    1287         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
    1288         public static object ExecuteScalar(SqlTransaction transaction, string spName, params object[] parameterValues)
    1289         {
    1290             if (transaction == null) throw new ArgumentNullException("transaction");
    1291             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
    1292             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    1293 
    1294             // If we receive parameter values, we need to figure out where they go
    1295             if ((parameterValues != null) && (parameterValues.Length > 0))
    1296             {
    1297                 // PPull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    1298                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
    1299 
    1300                 // Assign the provided values to these parameters based on parameter order
    1301                 AssignParameterValues(commandParameters, parameterValues);
    1302 
    1303                 // Call the overload that takes an array of SqlParameters
    1304                 return ExecuteScalar(transaction, CommandType.StoredProcedure, spName, commandParameters);
    1305             }
    1306             else
    1307             {
    1308                 // Otherwise we can just call the SP without params
    1309                 return ExecuteScalar(transaction, CommandType.StoredProcedure, spName);
    1310             }
    1311         }
    1312 
    1313         #endregion ExecuteScalar    
    1314 
    1315         #region ExecuteXmlReader
    1316         /// <summary>
    1317         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. 
    1318         /// </summary>
    1319         /// <remarks>
    1320         /// e.g.:  
    1321         ///  XmlReader r = ExecuteXmlReader(conn, CommandType.StoredProcedure, "GetOrders");
    1322         /// </remarks>
    1323         /// <param name="connection">A valid SqlConnection</param>
    1324         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1325         /// <param name="commandText">The stored procedure name or T-SQL command using "FOR XML AUTO"</param>
    1326         /// <returns>An XmlReader containing the resultset generated by the command</returns>
    1327         public static XmlReader ExecuteXmlReader(SqlConnection connection, CommandType commandType, string commandText)
    1328         {
    1329             // Pass through the call providing null for the set of SqlParameters
    1330             return ExecuteXmlReader(connection, commandType, commandText, (SqlParameter[])null);
    1331         }
    1332 
    1333         /// <summary>
    1334         /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 
    1335         /// using the provided parameters.
    1336         /// </summary>
    1337         /// <remarks>
    1338         /// e.g.:  
    1339         ///  XmlReader r = ExecuteXmlReader(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
    1340         /// </remarks>
    1341         /// <param name="connection">A valid SqlConnection</param>
    1342         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1343         /// <param name="commandText">The stored procedure name or T-SQL command using "FOR XML AUTO"</param>
    1344         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
    1345         /// <returns>An XmlReader containing the resultset generated by the command</returns>
    1346         public static XmlReader ExecuteXmlReader(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
    1347         {
    1348             if (connection == null) throw new ArgumentNullException("connection");
    1349 
    1350             bool mustCloseConnection = false;
    1351             // Create a command and prepare it for execution
    1352             SqlCommand cmd = new SqlCommand();
    1353             try
    1354             {
    1355                 PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);
    1356 
    1357                 // Create the DataAdapter & DataSet
    1358                 XmlReader retval = cmd.ExecuteXmlReader();
    1359 
    1360                 // Detach the SqlParameters from the command object, so they can be used again
    1361                 cmd.Parameters.Clear();
    1362 
    1363                 return retval;
    1364             }
    1365             catch
    1366             {
    1367                 if (mustCloseConnection)
    1368                     connection.Close();
    1369                 throw;
    1370             }
    1371         }
    1372 
    1373         /// <summary>
    1374         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
    1375         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
    1376         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    1377         /// </summary>
    1378         /// <remarks>
    1379         /// This method provides no access to output parameters or the stored procedure's return value parameter.
    1380         /// 
    1381         /// e.g.:  
    1382         ///  XmlReader r = ExecuteXmlReader(conn, "GetOrders", 24, 36);
    1383         /// </remarks>
    1384         /// <param name="connection">A valid SqlConnection</param>
    1385         /// <param name="spName">The name of the stored procedure using "FOR XML AUTO"</param>
    1386         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
    1387         /// <returns>An XmlReader containing the resultset generated by the command</returns>
    1388         public static XmlReader ExecuteXmlReader(SqlConnection connection, string spName, params object[] parameterValues)
    1389         {
    1390             if (connection == null) throw new ArgumentNullException("connection");
    1391             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    1392 
    1393             // If we receive parameter values, we need to figure out where they go
    1394             if ((parameterValues != null) && (parameterValues.Length > 0))
    1395             {
    1396                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    1397                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
    1398 
    1399                 // Assign the provided values to these parameters based on parameter order
    1400                 AssignParameterValues(commandParameters, parameterValues);
    1401 
    1402                 // Call the overload that takes an array of SqlParameters
    1403                 return ExecuteXmlReader(connection, CommandType.StoredProcedure, spName, commandParameters);
    1404             }
    1405             else
    1406             {
    1407                 // Otherwise we can just call the SP without params
    1408                 return ExecuteXmlReader(connection, CommandType.StoredProcedure, spName);
    1409             }
    1410         }
    1411 
    1412         /// <summary>
    1413         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. 
    1414         /// </summary>
    1415         /// <remarks>
    1416         /// e.g.:  
    1417         ///  XmlReader r = ExecuteXmlReader(trans, CommandType.StoredProcedure, "GetOrders");
    1418         /// </remarks>
    1419         /// <param name="transaction">A valid SqlTransaction</param>
    1420         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1421         /// <param name="commandText">The stored procedure name or T-SQL command using "FOR XML AUTO"</param>
    1422         /// <returns>An XmlReader containing the resultset generated by the command</returns>
    1423         public static XmlReader ExecuteXmlReader(SqlTransaction transaction, CommandType commandType, string commandText)
    1424         {
    1425             // Pass through the call providing null for the set of SqlParameters
    1426             return ExecuteXmlReader(transaction, commandType, commandText, (SqlParameter[])null);
    1427         }
    1428 
    1429         /// <summary>
    1430         /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction
    1431         /// using the provided parameters.
    1432         /// </summary>
    1433         /// <remarks>
    1434         /// e.g.:  
    1435         ///  XmlReader r = ExecuteXmlReader(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
    1436         /// </remarks>
    1437         /// <param name="transaction">A valid SqlTransaction</param>
    1438         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1439         /// <param name="commandText">The stored procedure name or T-SQL command using "FOR XML AUTO"</param>
    1440         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
    1441         /// <returns>An XmlReader containing the resultset generated by the command</returns>
    1442         public static XmlReader ExecuteXmlReader(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
    1443         {
    1444             if (transaction == null) throw new ArgumentNullException("transaction");
    1445             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
    1446 
    1447             // Create a command and prepare it for execution
    1448             SqlCommand cmd = new SqlCommand();
    1449             bool mustCloseConnection = false;
    1450             PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
    1451 
    1452             // Create the DataAdapter & DataSet
    1453             XmlReader retval = cmd.ExecuteXmlReader();
    1454 
    1455             // Detach the SqlParameters from the command object, so they can be used again
    1456             cmd.Parameters.Clear();
    1457             return retval;
    1458         }
    1459 
    1460         /// <summary>
    1461         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified 
    1462         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
    1463         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    1464         /// </summary>
    1465         /// <remarks>
    1466         /// This method provides no access to output parameters or the stored procedure's return value parameter.
    1467         /// 
    1468         /// e.g.:  
    1469         ///  XmlReader r = ExecuteXmlReader(trans, "GetOrders", 24, 36);
    1470         /// </remarks>
    1471         /// <param name="transaction">A valid SqlTransaction</param>
    1472         /// <param name="spName">The name of the stored procedure</param>
    1473         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
    1474         /// <returns>A dataset containing the resultset generated by the command</returns>
    1475         public static XmlReader ExecuteXmlReader(SqlTransaction transaction, string spName, params object[] parameterValues)
    1476         {
    1477             if (transaction == null) throw new ArgumentNullException("transaction");
    1478             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
    1479             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    1480 
    1481             // If we receive parameter values, we need to figure out where they go
    1482             if ((parameterValues != null) && (parameterValues.Length > 0))
    1483             {
    1484                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    1485                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
    1486 
    1487                 // Assign the provided values to these parameters based on parameter order
    1488                 AssignParameterValues(commandParameters, parameterValues);
    1489 
    1490                 // Call the overload that takes an array of SqlParameters
    1491                 return ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
    1492             }
    1493             else
    1494             {
    1495                 // Otherwise we can just call the SP without params
    1496                 return ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName);
    1497             }
    1498         }
    1499 
    1500         #endregion ExecuteXmlReader
    1501 
    1502         #region FillDataset
    1503         /// <summary>
    1504         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in 
    1505         /// the connection string. 
    1506         /// </summary>
    1507         /// <remarks>
    1508         /// e.g.:  
    1509         ///  FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"});
    1510         /// </remarks>
    1511         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    1512         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1513         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    1514         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
    1515         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
    1516         /// by a user defined name (probably the actual table name)</param>
    1517         public static void FillDataset(string connectionString, CommandType commandType, string commandText, DataSet dataSet, string[] tableNames)
    1518         {
    1519             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
    1520             if (dataSet == null) throw new ArgumentNullException("dataSet");
    1521 
    1522             // Create & open a SqlConnection, and dispose of it after we are done
    1523             using (SqlConnection connection = new SqlConnection(connectionString))
    1524             {
    1525                 connection.Open();
    1526 
    1527                 // Call the overload that takes a connection in place of the connection string
    1528                 FillDataset(connection, commandType, commandText, dataSet, tableNames);
    1529             }
    1530         }
    1531 
    1532         /// <summary>
    1533         /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string 
    1534         /// using the provided parameters.
    1535         /// </summary>
    1536         /// <remarks>
    1537         /// e.g.:  
    1538         ///  FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24));
    1539         /// </remarks>
    1540         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    1541         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1542         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    1543         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
    1544         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
    1545         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
    1546         /// by a user defined name (probably the actual table name)
    1547         /// </param>
    1548         public static void FillDataset(string connectionString, CommandType commandType,
    1549             string commandText, DataSet dataSet, string[] tableNames,
    1550             params SqlParameter[] commandParameters)
    1551         {
    1552             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
    1553             if (dataSet == null) throw new ArgumentNullException("dataSet");
    1554             // Create & open a SqlConnection, and dispose of it after we are done
    1555             using (SqlConnection connection = new SqlConnection(connectionString))
    1556             {
    1557                 connection.Open();
    1558 
    1559                 // Call the overload that takes a connection in place of the connection string
    1560                 FillDataset(connection, commandType, commandText, dataSet, tableNames, commandParameters);
    1561             }
    1562         }
    1563 
    1564         /// <summary>
    1565         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 
    1566         /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
    1567         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    1568         /// </summary>
    1569         /// <remarks>
    1570         /// This method provides no access to output parameters or the stored procedure's return value parameter.
    1571         /// 
    1572         /// e.g.:  
    1573         ///  FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, 24);
    1574         /// </remarks>
    1575         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    1576         /// <param name="spName">The name of the stored procedure</param>
    1577         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
    1578         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
    1579         /// by a user defined name (probably the actual table name)
    1580         /// </param>    
    1581         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
    1582         public static void FillDataset(string connectionString, string spName,
    1583             DataSet dataSet, string[] tableNames,
    1584             params object[] parameterValues)
    1585         {
    1586             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
    1587             if (dataSet == null) throw new ArgumentNullException("dataSet");
    1588             // Create & open a SqlConnection, and dispose of it after we are done
    1589             using (SqlConnection connection = new SqlConnection(connectionString))
    1590             {
    1591                 connection.Open();
    1592 
    1593                 // Call the overload that takes a connection in place of the connection string
    1594                 FillDataset(connection, spName, dataSet, tableNames, parameterValues);
    1595             }
    1596         }
    1597 
    1598         /// <summary>
    1599         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. 
    1600         /// </summary>
    1601         /// <remarks>
    1602         /// e.g.:  
    1603         ///  FillDataset(conn, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"});
    1604         /// </remarks>
    1605         /// <param name="connection">A valid SqlConnection</param>
    1606         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1607         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    1608         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
    1609         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
    1610         /// by a user defined name (probably the actual table name)
    1611         /// </param>    
    1612         public static void FillDataset(SqlConnection connection, CommandType commandType,
    1613             string commandText, DataSet dataSet, string[] tableNames)
    1614         {
    1615             FillDataset(connection, commandType, commandText, dataSet, tableNames, null);
    1616         }
    1617 
    1618         /// <summary>
    1619         /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 
    1620         /// using the provided parameters.
    1621         /// </summary>
    1622         /// <remarks>
    1623         /// e.g.:  
    1624         ///  FillDataset(conn, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24));
    1625         /// </remarks>
    1626         /// <param name="connection">A valid SqlConnection</param>
    1627         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1628         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    1629         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
    1630         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
    1631         /// by a user defined name (probably the actual table name)
    1632         /// </param>
    1633         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
    1634         public static void FillDataset(SqlConnection connection, CommandType commandType,
    1635             string commandText, DataSet dataSet, string[] tableNames,
    1636             params SqlParameter[] commandParameters)
    1637         {
    1638             FillDataset(connection, null, commandType, commandText, dataSet, tableNames, commandParameters);
    1639         }
    1640 
    1641         /// <summary>
    1642         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
    1643         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
    1644         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    1645         /// </summary>
    1646         /// <remarks>
    1647         /// This method provides no access to output parameters or the stored procedure's return value parameter.
    1648         /// 
    1649         /// e.g.:  
    1650         ///  FillDataset(conn, "GetOrders", ds, new string[] {"orders"}, 24, 36);
    1651         /// </remarks>
    1652         /// <param name="connection">A valid SqlConnection</param>
    1653         /// <param name="spName">The name of the stored procedure</param>
    1654         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
    1655         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
    1656         /// by a user defined name (probably the actual table name)
    1657         /// </param>
    1658         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
    1659         public static void FillDataset(SqlConnection connection, string spName,
    1660             DataSet dataSet, string[] tableNames,
    1661             params object[] parameterValues)
    1662         {
    1663             if (connection == null) throw new ArgumentNullException("connection");
    1664             if (dataSet == null) throw new ArgumentNullException("dataSet");
    1665             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    1666 
    1667             // If we receive parameter values, we need to figure out where they go
    1668             if ((parameterValues != null) && (parameterValues.Length > 0))
    1669             {
    1670                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    1671                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
    1672 
    1673                 // Assign the provided values to these parameters based on parameter order
    1674                 AssignParameterValues(commandParameters, parameterValues);
    1675 
    1676                 // Call the overload that takes an array of SqlParameters
    1677                 FillDataset(connection, CommandType.StoredProcedure, spName, dataSet, tableNames, commandParameters);
    1678             }
    1679             else
    1680             {
    1681                 // Otherwise we can just call the SP without params
    1682                 FillDataset(connection, CommandType.StoredProcedure, spName, dataSet, tableNames);
    1683             }
    1684         }
    1685 
    1686         /// <summary>
    1687         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. 
    1688         /// </summary>
    1689         /// <remarks>
    1690         /// e.g.:  
    1691         ///  FillDataset(trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"});
    1692         /// </remarks>
    1693         /// <param name="transaction">A valid SqlTransaction</param>
    1694         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1695         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    1696         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
    1697         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
    1698         /// by a user defined name (probably the actual table name)
    1699         /// </param>
    1700         public static void FillDataset(SqlTransaction transaction, CommandType commandType,
    1701             string commandText,
    1702             DataSet dataSet, string[] tableNames)
    1703         {
    1704             FillDataset(transaction, commandType, commandText, dataSet, tableNames, null);
    1705         }
    1706 
    1707         /// <summary>
    1708         /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction
    1709         /// using the provided parameters.
    1710         /// </summary>
    1711         /// <remarks>
    1712         /// e.g.:  
    1713         ///  FillDataset(trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24));
    1714         /// </remarks>
    1715         /// <param name="transaction">A valid SqlTransaction</param>
    1716         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1717         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    1718         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
    1719         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
    1720         /// by a user defined name (probably the actual table name)
    1721         /// </param>
    1722         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
    1723         public static void FillDataset(SqlTransaction transaction, CommandType commandType,
    1724             string commandText, DataSet dataSet, string[] tableNames,
    1725             params SqlParameter[] commandParameters)
    1726         {
    1727             FillDataset(transaction.Connection, transaction, commandType, commandText, dataSet, tableNames, commandParameters);
    1728         }
    1729 
    1730         /// <summary>
    1731         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified 
    1732         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
    1733         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    1734         /// </summary>
    1735         /// <remarks>
    1736         /// This method provides no access to output parameters or the stored procedure's return value parameter.
    1737         /// 
    1738         /// e.g.:  
    1739         ///  FillDataset(trans, "GetOrders", ds, new string[]{"orders"}, 24, 36);
    1740         /// </remarks>
    1741         /// <param name="transaction">A valid SqlTransaction</param>
    1742         /// <param name="spName">The name of the stored procedure</param>
    1743         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
    1744         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
    1745         /// by a user defined name (probably the actual table name)
    1746         /// </param>
    1747         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
    1748         public static void FillDataset(SqlTransaction transaction, string spName,
    1749             DataSet dataSet, string[] tableNames,
    1750             params object[] parameterValues)
    1751         {
    1752             if (transaction == null) throw new ArgumentNullException("transaction");
    1753             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
    1754             if (dataSet == null) throw new ArgumentNullException("dataSet");
    1755             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    1756 
    1757             // If we receive parameter values, we need to figure out where they go
    1758             if ((parameterValues != null) && (parameterValues.Length > 0))
    1759             {
    1760                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    1761                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
    1762 
    1763                 // Assign the provided values to these parameters based on parameter order
    1764                 AssignParameterValues(commandParameters, parameterValues);
    1765 
    1766                 // Call the overload that takes an array of SqlParameters
    1767                 FillDataset(transaction, CommandType.StoredProcedure, spName, dataSet, tableNames, commandParameters);
    1768             }
    1769             else
    1770             {
    1771                 // Otherwise we can just call the SP without params
    1772                 FillDataset(transaction, CommandType.StoredProcedure, spName, dataSet, tableNames);
    1773             }
    1774         }
    1775 
    1776         /// <summary>
    1777         /// Private helper method that execute a SqlCommand (that returns a resultset) against the specified SqlTransaction and SqlConnection
    1778         /// using the provided parameters.
    1779         /// </summary>
    1780         /// <remarks>
    1781         /// e.g.:  
    1782         ///  FillDataset(conn, trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24));
    1783         /// </remarks>
    1784         /// <param name="connection">A valid SqlConnection</param>
    1785         /// <param name="transaction">A valid SqlTransaction</param>
    1786         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
    1787         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    1788         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
    1789         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
    1790         /// by a user defined name (probably the actual table name)
    1791         /// </param>
    1792         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
    1793         private static void FillDataset(SqlConnection connection, SqlTransaction transaction, CommandType commandType,
    1794             string commandText, DataSet dataSet, string[] tableNames,
    1795             params SqlParameter[] commandParameters)
    1796         {
    1797             if (connection == null) throw new ArgumentNullException("connection");
    1798             if (dataSet == null) throw new ArgumentNullException("dataSet");
    1799 
    1800             // Create a command and prepare it for execution
    1801             SqlCommand command = new SqlCommand();
    1802             bool mustCloseConnection = false;
    1803             PrepareCommand(command, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
    1804 
    1805             // Create the DataAdapter & DataSet
    1806             using (SqlDataAdapter dataAdapter = new SqlDataAdapter(command))
    1807             {
    1808 
    1809                 // Add the table mappings specified by the user
    1810                 if (tableNames != null && tableNames.Length > 0)
    1811                 {
    1812                     string tableName = "Table";
    1813                     for (int index = 0; index < tableNames.Length; index++)
    1814                     {
    1815                         if (tableNames[index] == null || tableNames[index].Length == 0) throw new ArgumentException("The tableNames parameter must contain a list of tables, a value was provided as null or empty string.", "tableNames");
    1816                         dataAdapter.TableMappings.Add(tableName, tableNames[index]);
    1817                         tableName += (index + 1).ToString();
    1818                     }
    1819                 }
    1820 
    1821                 // Fill the DataSet using default values for DataTable names, etc
    1822                 dataAdapter.Fill(dataSet);
    1823 
    1824                 // Detach the SqlParameters from the command object, so they can be used again
    1825                 command.Parameters.Clear();
    1826             }
    1827 
    1828             if (mustCloseConnection)
    1829                 connection.Close();
    1830         }
    1831         #endregion
    1832 
    1833         #region UpdateDataset
    1834         /// <summary>
    1835         /// Executes the respective command for each inserted, updated, or deleted row in the DataSet.
    1836         /// </summary>
    1837         /// <remarks>
    1838         /// e.g.:  
    1839         ///  UpdateDataset(conn, insertCommand, deleteCommand, updateCommand, dataSet, "Order");
    1840         /// </remarks>
    1841         /// <param name="insertCommand">A valid transact-SQL statement or stored procedure to insert new records into the data source</param>
    1842         /// <param name="deleteCommand">A valid transact-SQL statement or stored procedure to delete records from the data source</param>
    1843         /// <param name="updateCommand">A valid transact-SQL statement or stored procedure used to update records in the data source</param>
    1844         /// <param name="dataSet">The DataSet used to update the data source</param>
    1845         /// <param name="tableName">The DataTable used to update the data source.</param>
    1846         public static void UpdateDataset(SqlCommand insertCommand, SqlCommand deleteCommand, SqlCommand updateCommand, DataSet dataSet, string tableName)
    1847         {
    1848             if (insertCommand == null) throw new ArgumentNullException("insertCommand");
    1849             if (deleteCommand == null) throw new ArgumentNullException("deleteCommand");
    1850             if (updateCommand == null) throw new ArgumentNullException("updateCommand");
    1851             if (tableName == null || tableName.Length == 0) throw new ArgumentNullException("tableName");
    1852 
    1853             // Create a SqlDataAdapter, and dispose of it after we are done
    1854             using (SqlDataAdapter dataAdapter = new SqlDataAdapter())
    1855             {
    1856                 // Set the data adapter commands
    1857                 dataAdapter.UpdateCommand = updateCommand;
    1858                 dataAdapter.InsertCommand = insertCommand;
    1859                 dataAdapter.DeleteCommand = deleteCommand;
    1860 
    1861                 // Update the dataset changes in the data source
    1862                 dataAdapter.Update(dataSet, tableName);
    1863 
    1864                 // Commit all the changes made to the DataSet
    1865                 dataSet.AcceptChanges();
    1866             }
    1867         }
    1868         #endregion
    1869 
    1870         #region CreateCommand
    1871         /// <summary>
    1872         /// Simplify the creation of a Sql command object by allowing
    1873         /// a stored procedure and optional parameters to be provided
    1874         /// </summary>
    1875         /// <remarks>
    1876         /// e.g.:  
    1877         ///  SqlCommand command = CreateCommand(conn, "AddCustomer", "CustomerID", "CustomerName");
    1878         /// </remarks>
    1879         /// <param name="connection">A valid SqlConnection object</param>
    1880         /// <param name="spName">The name of the stored procedure</param>
    1881         /// <param name="sourceColumns">An array of string to be assigned as the source columns of the stored procedure parameters</param>
    1882         /// <returns>A valid SqlCommand object</returns>
    1883         public static SqlCommand CreateCommand(SqlConnection connection, string spName, params string[] sourceColumns)
    1884         {
    1885             if (connection == null) throw new ArgumentNullException("connection");
    1886             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    1887 
    1888             // Create a SqlCommand
    1889             SqlCommand cmd = new SqlCommand(spName, connection);
    1890             cmd.CommandType = CommandType.StoredProcedure;
    1891 
    1892             // If we receive parameter values, we need to figure out where they go
    1893             if ((sourceColumns != null) && (sourceColumns.Length > 0))
    1894             {
    1895                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    1896                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
    1897 
    1898                 // Assign the provided source columns to these parameters based on parameter order
    1899                 for (int index = 0; index < sourceColumns.Length; index++)
    1900                     commandParameters[index].SourceColumn = sourceColumns[index];
    1901 
    1902                 // Attach the discovered parameters to the SqlCommand object
    1903                 AttachParameters(cmd, commandParameters);
    1904             }
    1905 
    1906             return cmd;
    1907         }
    1908         #endregion
    1909 
    1910         #region ExecuteNonQueryTypedParams
    1911         /// <summary>
    1912         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the database specified in 
    1913         /// the connection string using the dataRow column values as the stored procedure's parameters values.
    1914         /// This method will query the database to discover the parameters for the 
    1915         /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.
    1916         /// </summary>
    1917         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    1918         /// <param name="spName">The name of the stored procedure</param>
    1919         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
    1920         /// <returns>An int representing the number of rows affected by the command</returns>
    1921         public static int ExecuteNonQueryTypedParams(String connectionString, String spName, DataRow dataRow)
    1922         {
    1923             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
    1924             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    1925 
    1926             // If the row has values, the store procedure parameters must be initialized
    1927             if (dataRow != null && dataRow.ItemArray.Length > 0)
    1928             {
    1929                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    1930                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
    1931 
    1932                 // Set the parameters values
    1933                 AssignParameterValues(commandParameters, dataRow);
    1934 
    1935                 return SqlHelper.ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters);
    1936             }
    1937             else
    1938             {
    1939                 return SqlHelper.ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName);
    1940             }
    1941         }
    1942 
    1943         /// <summary>
    1944         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified SqlConnection 
    1945         /// using the dataRow column values as the stored procedure's parameters values.  
    1946         /// This method will query the database to discover the parameters for the 
    1947         /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.
    1948         /// </summary>
    1949         /// <param name="connection">A valid SqlConnection object</param>
    1950         /// <param name="spName">The name of the stored procedure</param>
    1951         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
    1952         /// <returns>An int representing the number of rows affected by the command</returns>
    1953         public static int ExecuteNonQueryTypedParams(SqlConnection connection, String spName, DataRow dataRow)
    1954         {
    1955             if (connection == null) throw new ArgumentNullException("connection");
    1956             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    1957 
    1958             // If the row has values, the store procedure parameters must be initialized
    1959             if (dataRow != null && dataRow.ItemArray.Length > 0)
    1960             {
    1961                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    1962                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
    1963 
    1964                 // Set the parameters values
    1965                 AssignParameterValues(commandParameters, dataRow);
    1966 
    1967                 return SqlHelper.ExecuteNonQuery(connection, CommandType.StoredProcedure, spName, commandParameters);
    1968             }
    1969             else
    1970             {
    1971                 return SqlHelper.ExecuteNonQuery(connection, CommandType.StoredProcedure, spName);
    1972             }
    1973         }
    1974 
    1975         /// <summary>
    1976         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified
    1977         /// SqlTransaction using the dataRow column values as the stored procedure's parameters values.
    1978         /// This method will query the database to discover the parameters for the 
    1979         /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.
    1980         /// </summary>
    1981         /// <param name="transaction">A valid SqlTransaction object</param>
    1982         /// <param name="spName">The name of the stored procedure</param>
    1983         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
    1984         /// <returns>An int representing the number of rows affected by the command</returns>
    1985         public static int ExecuteNonQueryTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
    1986         {
    1987             if (transaction == null) throw new ArgumentNullException("transaction");
    1988             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
    1989             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    1990 
    1991             // Sf the row has values, the store procedure parameters must be initialized
    1992             if (dataRow != null && dataRow.ItemArray.Length > 0)
    1993             {
    1994                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    1995                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
    1996 
    1997                 // Set the parameters values
    1998                 AssignParameterValues(commandParameters, dataRow);
    1999 
    2000                 return SqlHelper.ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName, commandParameters);
    2001             }
    2002             else
    2003             {
    2004                 return SqlHelper.ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName);
    2005             }
    2006         }
    2007         #endregion
    2008 
    2009         #region ExecuteDatasetTypedParams
    2010         /// <summary>
    2011         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 
    2012         /// the connection string using the dataRow column values as the stored procedure's parameters values.
    2013         /// This method will query the database to discover the parameters for the 
    2014         /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.
    2015         /// </summary>
    2016         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    2017         /// <param name="spName">The name of the stored procedure</param>
    2018         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
    2019         /// <returns>A dataset containing the resultset generated by the command</returns>
    2020         public static DataSet ExecuteDatasetTypedParams(string connectionString, String spName, DataRow dataRow)
    2021         {
    2022             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
    2023             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    2024 
    2025             //If the row has values, the store procedure parameters must be initialized
    2026             if (dataRow != null && dataRow.ItemArray.Length > 0)
    2027             {
    2028                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    2029                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
    2030 
    2031                 // Set the parameters values
    2032                 AssignParameterValues(commandParameters, dataRow);
    2033 
    2034                 return SqlHelper.ExecuteDataset(connectionString, CommandType.StoredProcedure, spName, commandParameters);
    2035             }
    2036             else
    2037             {
    2038                 return SqlHelper.ExecuteDataset(connectionString, CommandType.StoredProcedure, spName);
    2039             }
    2040         }
    2041 
    2042         /// <summary>
    2043         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
    2044         /// using the dataRow column values as the store procedure's parameters values.
    2045         /// This method will query the database to discover the parameters for the 
    2046         /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.
    2047         /// </summary>
    2048         /// <param name="connection">A valid SqlConnection object</param>
    2049         /// <param name="spName">The name of the stored procedure</param>
    2050         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
    2051         /// <returns>A dataset containing the resultset generated by the command</returns>
    2052         public static DataSet ExecuteDatasetTypedParams(SqlConnection connection, String spName, DataRow dataRow)
    2053         {
    2054             if (connection == null) throw new ArgumentNullException("connection");
    2055             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    2056 
    2057             // If the row has values, the store procedure parameters must be initialized
    2058             if (dataRow != null && dataRow.ItemArray.Length > 0)
    2059             {
    2060                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    2061                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
    2062 
    2063                 // Set the parameters values
    2064                 AssignParameterValues(commandParameters, dataRow);
    2065 
    2066                 return SqlHelper.ExecuteDataset(connection, CommandType.StoredProcedure, spName, commandParameters);
    2067             }
    2068             else
    2069             {
    2070                 return SqlHelper.ExecuteDataset(connection, CommandType.StoredProcedure, spName);
    2071             }
    2072         }
    2073 
    2074         /// <summary>
    2075         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlTransaction 
    2076         /// using the dataRow column values as the stored procedure's parameters values.
    2077         /// This method will query the database to discover the parameters for the 
    2078         /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.
    2079         /// </summary>
    2080         /// <param name="transaction">A valid SqlTransaction object</param>
    2081         /// <param name="spName">The name of the stored procedure</param>
    2082         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
    2083         /// <returns>A dataset containing the resultset generated by the command</returns>
    2084         public static DataSet ExecuteDatasetTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
    2085         {
    2086             if (transaction == null) throw new ArgumentNullException("transaction");
    2087             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
    2088             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    2089 
    2090             // If the row has values, the store procedure parameters must be initialized
    2091             if (dataRow != null && dataRow.ItemArray.Length > 0)
    2092             {
    2093                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    2094                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
    2095 
    2096                 // Set the parameters values
    2097                 AssignParameterValues(commandParameters, dataRow);
    2098 
    2099                 return SqlHelper.ExecuteDataset(transaction, CommandType.StoredProcedure, spName, commandParameters);
    2100             }
    2101             else
    2102             {
    2103                 return SqlHelper.ExecuteDataset(transaction, CommandType.StoredProcedure, spName);
    2104             }
    2105         }
    2106 
    2107         #endregion
    2108 
    2109         #region ExecuteReaderTypedParams
    2110         /// <summary>
    2111         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 
    2112         /// the connection string using the dataRow column values as the stored procedure's parameters values.
    2113         /// This method will query the database to discover the parameters for the 
    2114         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    2115         /// </summary>
    2116         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    2117         /// <param name="spName">The name of the stored procedure</param>
    2118         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
    2119         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
    2120         public static SqlDataReader ExecuteReaderTypedParams(String connectionString, String spName, DataRow dataRow)
    2121         {
    2122             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
    2123             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    2124 
    2125             // If the row has values, the store procedure parameters must be initialized
    2126             if (dataRow != null && dataRow.ItemArray.Length > 0)
    2127             {
    2128                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    2129                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
    2130 
    2131                 // Set the parameters values
    2132                 AssignParameterValues(commandParameters, dataRow);
    2133 
    2134                 return SqlHelper.ExecuteReader(connectionString, CommandType.StoredProcedure, spName, commandParameters);
    2135             }
    2136             else
    2137             {
    2138                 return SqlHelper.ExecuteReader(connectionString, CommandType.StoredProcedure, spName);
    2139             }
    2140         }
    2141 
    2142 
    2143         /// <summary>
    2144         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
    2145         /// using the dataRow column values as the stored procedure's parameters values.
    2146         /// This method will query the database to discover the parameters for the 
    2147         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    2148         /// </summary>
    2149         /// <param name="connection">A valid SqlConnection object</param>
    2150         /// <param name="spName">The name of the stored procedure</param>
    2151         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
    2152         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
    2153         public static SqlDataReader ExecuteReaderTypedParams(SqlConnection connection, String spName, DataRow dataRow)
    2154         {
    2155             if (connection == null) throw new ArgumentNullException("connection");
    2156             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    2157 
    2158             // If the row has values, the store procedure parameters must be initialized
    2159             if (dataRow != null && dataRow.ItemArray.Length > 0)
    2160             {
    2161                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    2162                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
    2163 
    2164                 // Set the parameters values
    2165                 AssignParameterValues(commandParameters, dataRow);
    2166 
    2167                 return SqlHelper.ExecuteReader(connection, CommandType.StoredProcedure, spName, commandParameters);
    2168             }
    2169             else
    2170             {
    2171                 return SqlHelper.ExecuteReader(connection, CommandType.StoredProcedure, spName);
    2172             }
    2173         }
    2174 
    2175         /// <summary>
    2176         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlTransaction 
    2177         /// using the dataRow column values as the stored procedure's parameters values.
    2178         /// This method will query the database to discover the parameters for the 
    2179         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    2180         /// </summary>
    2181         /// <param name="transaction">A valid SqlTransaction object</param>
    2182         /// <param name="spName">The name of the stored procedure</param>
    2183         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
    2184         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
    2185         public static SqlDataReader ExecuteReaderTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
    2186         {
    2187             if (transaction == null) throw new ArgumentNullException("transaction");
    2188             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
    2189             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    2190 
    2191             // If the row has values, the store procedure parameters must be initialized
    2192             if (dataRow != null && dataRow.ItemArray.Length > 0)
    2193             {
    2194                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    2195                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
    2196 
    2197                 // Set the parameters values
    2198                 AssignParameterValues(commandParameters, dataRow);
    2199 
    2200                 return SqlHelper.ExecuteReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
    2201             }
    2202             else
    2203             {
    2204                 return SqlHelper.ExecuteReader(transaction, CommandType.StoredProcedure, spName);
    2205             }
    2206         }
    2207         #endregion
    2208 
    2209         #region ExecuteScalarTypedParams
    2210         /// <summary>
    2211         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the database specified in 
    2212         /// the connection string using the dataRow column values as the stored procedure's parameters values.
    2213         /// This method will query the database to discover the parameters for the 
    2214         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    2215         /// </summary>
    2216         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    2217         /// <param name="spName">The name of the stored procedure</param>
    2218         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
    2219         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
    2220         public static object ExecuteScalarTypedParams(String connectionString, String spName, DataRow dataRow)
    2221         {
    2222             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
    2223             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    2224 
    2225             // If the row has values, the store procedure parameters must be initialized
    2226             if (dataRow != null && dataRow.ItemArray.Length > 0)
    2227             {
    2228                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    2229                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
    2230 
    2231                 // Set the parameters values
    2232                 AssignParameterValues(commandParameters, dataRow);
    2233 
    2234                 return SqlHelper.ExecuteScalar(connectionString, CommandType.StoredProcedure, spName, commandParameters);
    2235             }
    2236             else
    2237             {
    2238                 return SqlHelper.ExecuteScalar(connectionString, CommandType.StoredProcedure, spName);
    2239             }
    2240         }
    2241 
    2242         /// <summary>
    2243         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection 
    2244         /// using the dataRow column values as the stored procedure's parameters values.
    2245         /// This method will query the database to discover the parameters for the 
    2246         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    2247         /// </summary>
    2248         /// <param name="connection">A valid SqlConnection object</param>
    2249         /// <param name="spName">The name of the stored procedure</param>
    2250         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
    2251         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
    2252         public static object ExecuteScalarTypedParams(SqlConnection connection, String spName, DataRow dataRow)
    2253         {
    2254             if (connection == null) throw new ArgumentNullException("connection");
    2255             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    2256 
    2257             // If the row has values, the store procedure parameters must be initialized
    2258             if (dataRow != null && dataRow.ItemArray.Length > 0)
    2259             {
    2260                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    2261                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
    2262 
    2263                 // Set the parameters values
    2264                 AssignParameterValues(commandParameters, dataRow);
    2265 
    2266                 return SqlHelper.ExecuteScalar(connection, CommandType.StoredProcedure, spName, commandParameters);
    2267             }
    2268             else
    2269             {
    2270                 return SqlHelper.ExecuteScalar(connection, CommandType.StoredProcedure, spName);
    2271             }
    2272         }
    2273 
    2274         /// <summary>
    2275         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified SqlTransaction
    2276         /// using the dataRow column values as the stored procedure's parameters values.
    2277         /// This method will query the database to discover the parameters for the 
    2278         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    2279         /// </summary>
    2280         /// <param name="transaction">A valid SqlTransaction object</param>
    2281         /// <param name="spName">The name of the stored procedure</param>
    2282         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
    2283         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
    2284         public static object ExecuteScalarTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
    2285         {
    2286             if (transaction == null) throw new ArgumentNullException("transaction");
    2287             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
    2288             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    2289 
    2290             // If the row has values, the store procedure parameters must be initialized
    2291             if (dataRow != null && dataRow.ItemArray.Length > 0)
    2292             {
    2293                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    2294                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
    2295 
    2296                 // Set the parameters values
    2297                 AssignParameterValues(commandParameters, dataRow);
    2298 
    2299                 return SqlHelper.ExecuteScalar(transaction, CommandType.StoredProcedure, spName, commandParameters);
    2300             }
    2301             else
    2302             {
    2303                 return SqlHelper.ExecuteScalar(transaction, CommandType.StoredProcedure, spName);
    2304             }
    2305         }
    2306         #endregion
    2307 
    2308         #region ExecuteXmlReaderTypedParams
    2309         /// <summary>
    2310         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
    2311         /// using the dataRow column values as the stored procedure's parameters values.
    2312         /// This method will query the database to discover the parameters for the 
    2313         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    2314         /// </summary>
    2315         /// <param name="connection">A valid SqlConnection object</param>
    2316         /// <param name="spName">The name of the stored procedure</param>
    2317         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
    2318         /// <returns>An XmlReader containing the resultset generated by the command</returns>
    2319         public static XmlReader ExecuteXmlReaderTypedParams(SqlConnection connection, String spName, DataRow dataRow)
    2320         {
    2321             if (connection == null) throw new ArgumentNullException("connection");
    2322             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    2323 
    2324             // If the row has values, the store procedure parameters must be initialized
    2325             if (dataRow != null && dataRow.ItemArray.Length > 0)
    2326             {
    2327                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    2328                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
    2329 
    2330                 // Set the parameters values
    2331                 AssignParameterValues(commandParameters, dataRow);
    2332 
    2333                 return SqlHelper.ExecuteXmlReader(connection, CommandType.StoredProcedure, spName, commandParameters);
    2334             }
    2335             else
    2336             {
    2337                 return SqlHelper.ExecuteXmlReader(connection, CommandType.StoredProcedure, spName);
    2338             }
    2339         }
    2340 
    2341         /// <summary>
    2342         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlTransaction 
    2343         /// using the dataRow column values as the stored procedure's parameters values.
    2344         /// This method will query the database to discover the parameters for the 
    2345         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    2346         /// </summary>
    2347         /// <param name="transaction">A valid SqlTransaction object</param>
    2348         /// <param name="spName">The name of the stored procedure</param>
    2349         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
    2350         /// <returns>An XmlReader containing the resultset generated by the command</returns>
    2351         public static XmlReader ExecuteXmlReaderTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
    2352         {
    2353             if (transaction == null) throw new ArgumentNullException("transaction");
    2354             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
    2355             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    2356 
    2357             // If the row has values, the store procedure parameters must be initialized
    2358             if (dataRow != null && dataRow.ItemArray.Length > 0)
    2359             {
    2360                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
    2361                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
    2362 
    2363                 // Set the parameters values
    2364                 AssignParameterValues(commandParameters, dataRow);
    2365 
    2366                 return SqlHelper.ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
    2367             }
    2368             else
    2369             {
    2370                 return SqlHelper.ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName);
    2371             }
    2372         }
    2373         #endregion
    2374 
    2375     }
    2376 
    2377     /// <summary>
    2378     /// SqlHelperParameterCache provides functions to leverage a static cache of procedure parameters, and the
    2379     /// ability to discover parameters for stored procedures at run-time.
    2380     /// </summary>
    2381     public sealed class SqlHelperParameterCache
    2382     {
    2383         #region private methods, variables, and constructors
    2384 
    2385         //Since this class provides only static methods, make the default constructor private to prevent 
    2386         //instances from being created with "new SqlHelperParameterCache()"
    2387         private SqlHelperParameterCache() { }
    2388 
    2389         private static Hashtable paramCache = Hashtable.Synchronized(new Hashtable());
    2390 
    2391         /// <summary>
    2392         /// Resolve at run time the appropriate set of SqlParameters for a stored procedure
    2393         /// </summary>
    2394         /// <param name="connection">A valid SqlConnection object</param>
    2395         /// <param name="spName">The name of the stored procedure</param>
    2396         /// <param name="includeReturnValueParameter">Whether or not to include their return value parameter</param>
    2397         /// <returns>The parameter array discovered.</returns>
    2398         private static SqlParameter[] DiscoverSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter)
    2399         {
    2400             if (connection == null) throw new ArgumentNullException("connection");
    2401             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    2402 
    2403             SqlCommand cmd = new SqlCommand(spName, connection);
    2404             cmd.CommandType = CommandType.StoredProcedure;
    2405 
    2406             connection.Open();
    2407             SqlCommandBuilder.DeriveParameters(cmd);
    2408             connection.Close();
    2409 
    2410             if (!includeReturnValueParameter)
    2411             {
    2412                 cmd.Parameters.RemoveAt(0);
    2413             }
    2414 
    2415             SqlParameter[] discoveredParameters = new SqlParameter[cmd.Parameters.Count];
    2416 
    2417             cmd.Parameters.CopyTo(discoveredParameters, 0);
    2418 
    2419             // Init the parameters with a DBNull value
    2420             foreach (SqlParameter discoveredParameter in discoveredParameters)
    2421             {
    2422                 discoveredParameter.Value = DBNull.Value;
    2423             }
    2424             return discoveredParameters;
    2425         }
    2426 
    2427         /// <summary>
    2428         /// Deep copy of cached SqlParameter array
    2429         /// </summary>
    2430         /// <param name="originalParameters"></param>
    2431         /// <returns></returns>
    2432         private static SqlParameter[] CloneParameters(SqlParameter[] originalParameters)
    2433         {
    2434             SqlParameter[] clonedParameters = new SqlParameter[originalParameters.Length];
    2435 
    2436             for (int i = 0, j = originalParameters.Length; i < j; i++)
    2437             {
    2438                 clonedParameters[i] = (SqlParameter)((ICloneable)originalParameters[i]).Clone();
    2439             }
    2440 
    2441             return clonedParameters;
    2442         }
    2443 
    2444         #endregion private methods, variables, and constructors
    2445 
    2446         #region caching functions
    2447 
    2448         /// <summary>
    2449         /// Add parameter array to the cache
    2450         /// </summary>
    2451         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    2452         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    2453         /// <param name="commandParameters">An array of SqlParamters to be cached</param>
    2454         public static void CacheParameterSet(string connectionString, string commandText, params SqlParameter[] commandParameters)
    2455         {
    2456             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
    2457             if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");
    2458 
    2459             string hashKey = connectionString + ":" + commandText;
    2460 
    2461             paramCache[hashKey] = commandParameters;
    2462         }
    2463 
    2464         /// <summary>
    2465         /// Retrieve a parameter array from the cache
    2466         /// </summary>
    2467         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    2468         /// <param name="commandText">The stored procedure name or T-SQL command</param>
    2469         /// <returns>An array of SqlParamters</returns>
    2470         public static SqlParameter[] GetCachedParameterSet(string connectionString, string commandText)
    2471         {
    2472             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
    2473             if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");
    2474 
    2475             string hashKey = connectionString + ":" + commandText;
    2476 
    2477             SqlParameter[] cachedParameters = paramCache[hashKey] as SqlParameter[];
    2478             if (cachedParameters == null)
    2479             {
    2480                 return null;
    2481             }
    2482             else
    2483             {
    2484                 return CloneParameters(cachedParameters);
    2485             }
    2486         }
    2487 
    2488         #endregion caching functions
    2489 
    2490         #region Parameter Discovery Functions
    2491 
    2492         /// <summary>
    2493         /// Retrieves the set of SqlParameters appropriate for the stored procedure
    2494         /// </summary>
    2495         /// <remarks>
    2496         /// This method will query the database for this information, and then store it in a cache for future requests.
    2497         /// </remarks>
    2498         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    2499         /// <param name="spName">The name of the stored procedure</param>
    2500         /// <returns>An array of SqlParameters</returns>
    2501         public static SqlParameter[] GetSpParameterSet(string connectionString, string spName)
    2502         {
    2503             return GetSpParameterSet(connectionString, spName, false);
    2504         }
    2505 
    2506         /// <summary>
    2507         /// Retrieves the set of SqlParameters appropriate for the stored procedure
    2508         /// </summary>
    2509         /// <remarks>
    2510         /// This method will query the database for this information, and then store it in a cache for future requests.
    2511         /// </remarks>
    2512         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    2513         /// <param name="spName">The name of the stored procedure</param>
    2514         /// <param name="includeReturnValueParameter">A bool value indicating whether the return value parameter should be included in the results</param>
    2515         /// <returns>An array of SqlParameters</returns>
    2516         public static SqlParameter[] GetSpParameterSet(string connectionString, string spName, bool includeReturnValueParameter)
    2517         {
    2518             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
    2519             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    2520 
    2521             using (SqlConnection connection = new SqlConnection(connectionString))
    2522             {
    2523                 return GetSpParameterSetInternal(connection, spName, includeReturnValueParameter);
    2524             }
    2525         }
    2526 
    2527         /// <summary>
    2528         /// Retrieves the set of SqlParameters appropriate for the stored procedure
    2529         /// </summary>
    2530         /// <remarks>
    2531         /// This method will query the database for this information, and then store it in a cache for future requests.
    2532         /// </remarks>
    2533         /// <param name="connection">A valid SqlConnection object</param>
    2534         /// <param name="spName">The name of the stored procedure</param>
    2535         /// <returns>An array of SqlParameters</returns>
    2536         internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName)
    2537         {
    2538             return GetSpParameterSet(connection, spName, false);
    2539         }
    2540 
    2541         /// <summary>
    2542         /// Retrieves the set of SqlParameters appropriate for the stored procedure
    2543         /// </summary>
    2544         /// <remarks>
    2545         /// This method will query the database for this information, and then store it in a cache for future requests.
    2546         /// </remarks>
    2547         /// <param name="connection">A valid SqlConnection object</param>
    2548         /// <param name="spName">The name of the stored procedure</param>
    2549         /// <param name="includeReturnValueParameter">A bool value indicating whether the return value parameter should be included in the results</param>
    2550         /// <returns>An array of SqlParameters</returns>
    2551         internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter)
    2552         {
    2553             if (connection == null) throw new ArgumentNullException("connection");
    2554             using (SqlConnection clonedConnection = (SqlConnection)((ICloneable)connection).Clone())
    2555             {
    2556                 return GetSpParameterSetInternal(clonedConnection, spName, includeReturnValueParameter);
    2557             }
    2558         }
    2559 
    2560         /// <summary>
    2561         /// Retrieves the set of SqlParameters appropriate for the stored procedure
    2562         /// </summary>
    2563         /// <param name="connection">A valid SqlConnection object</param>
    2564         /// <param name="spName">The name of the stored procedure</param>
    2565         /// <param name="includeReturnValueParameter">A bool value indicating whether the return value parameter should be included in the results</param>
    2566         /// <returns>An array of SqlParameters</returns>
    2567         private static SqlParameter[] GetSpParameterSetInternal(SqlConnection connection, string spName, bool includeReturnValueParameter)
    2568         {
    2569             if (connection == null) throw new ArgumentNullException("connection");
    2570             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
    2571 
    2572             string hashKey = connection.ConnectionString + ":" + spName + (includeReturnValueParameter ? ":include ReturnValue Parameter" : "");
    2573 
    2574             SqlParameter[] cachedParameters;
    2575 
    2576             cachedParameters = paramCache[hashKey] as SqlParameter[];
    2577             if (cachedParameters == null)
    2578             {
    2579                 SqlParameter[] spParameters = DiscoverSpParameterSet(connection, spName, includeReturnValueParameter);
    2580                 paramCache[hashKey] = spParameters;
    2581                 cachedParameters = spParameters;
    2582             }
    2583 
    2584             return CloneParameters(cachedParameters);
    2585         }
    2586 
    2587         #endregion Parameter Discovery Functions
    2588 
    2589     }
    2590 }
    View Code

    作者:zscmj
    出处:http://www.cnblogs.com/zscmj/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    LInux常用命令:总结
    SpringBoot声明式事务(转)
    连接linux客户端工具
    查看servlet 3.0文档方法
    通过spring.io找spring历史版本
    归并排序(比希尔还要快)
    快速排序(比希尔排序还要快)
    希尔排序(交换式和移位式)
    插入排序
    选择排序(时间复杂度O(n^2))
  • 原文地址:https://www.cnblogs.com/zscmj/p/6024800.html
Copyright © 2011-2022 走看看