SqlHelper 帮助类

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

 

posted on 2017-12-06 10:19  蝸小牛  阅读(220)  评论(0)    收藏  举报

导航