首页 > 代码库 > 【2016-11-2】【坚持学习】【Day17】【微软 推出的SQLHelper】

【2016-11-2】【坚持学习】【Day17】【微软 推出的SQLHelper】

从网络上找到 微软原版本的SQLHelper,很多行代码。认真看了,学习了。
技术分享

 

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

 

【2016-11-2】【坚持学习】【Day17】【微软 推出的SQLHelper】