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

  • 相关阅读:
    poj 2352 Stars (树状数组)
    一.C语言:关键字、标识符和注释
    运算符:三目运算符,运算符优先级,sizeof,自增自减,取余
    ios app 上架AppStore
    为ios app添加广告条
    谓词
    正则表达式
    日期处理
    第一次往github上传文件步骤
    codeforce 375_2_b_c
  • 原文地址:https://www.cnblogs.com/lijinchang/p/1893457.html
Copyright © 2011-2022 走看看