微软的SQLHelper类

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值