SQLHelper

  今天學習了.net後,通過老師的一番講解,彷佛對它愈來愈渴望了,但願本身在接下來的學習當中,能很好的駕馭.net,加油吧,數據庫

  下面我分享一個操做SQL數據庫的代碼大全,謝謝觀賞。嘿嘿,仍是比較長的哦,app

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