SQLHelper.cs
Upload User: ghb7969
Upload Date: 2019-08-27
Package Size: 1060k
Code Size: 145k
Category:

ADO-ODBC

Development Platform:

Visual C++

  1. // ===============================================================================
  2. // Microsoft Data Access Application Block for .NET
  3. // http://msdn.microsoft.com/library/en-us/dnbda/html/daab-rm.asp
  4. //
  5. // SQLHelper.cs
  6. //
  7. // This file contains the implementations of the SqlHelper and SqlHelperParameterCache
  8. // classes.
  9. //
  10. // For more information see the Data Access Application Block Implementation Overview. 
  11. // ===============================================================================
  12. // Release history
  13. // VERSION DESCRIPTION
  14. //   2.0 Added support for FillDataset, UpdateDataset and "Param" helper methods
  15. //
  16. // ===============================================================================
  17. // Copyright (C) 2000-2001 Microsoft Corporation
  18. // All rights reserved.
  19. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
  20. // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
  21. // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR
  22. // FITNESS FOR A PARTICULAR PURPOSE.
  23. // ==============================================================================
  24. using System;
  25. using System.Data;
  26. using System.Xml;
  27. using System.Data.SqlClient;
  28. using System.Collections;
  29. namespace Microsoft.ApplicationBlocks.Data
  30. {
  31. /// <summary>
  32. /// The SqlHelper class is intended to encapsulate high performance, scalable best practices for 
  33. /// common uses of SqlClient
  34. /// </summary>
  35.     public sealed class SqlHelper
  36.     {
  37.         #region private utility methods & constructors
  38.         // Since this class provides only static methods, make the default constructor private to prevent 
  39.         // instances from being created with "new SqlHelper()"
  40.         private SqlHelper() {}
  41.         /// <summary>
  42.         /// This method is used to attach array of SqlParameters to a SqlCommand.
  43.         /// 
  44.         /// This method will assign a value of DbNull to any parameter with a direction of
  45.         /// InputOutput and a value of null.  
  46.         /// 
  47.         /// This behavior will prevent default values from being used, but
  48.         /// this will be the less common case than an intended pure output parameter (derived as InputOutput)
  49.         /// where the user provided no input value.
  50.         /// </summary>
  51.         /// <param name="command">The command to which the parameters will be added</param>
  52.         /// <param name="commandParameters">An array of SqlParameters to be added to command</param>
  53.         private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters)
  54.         {
  55. if( command == null ) throw new ArgumentNullException( "command" );
  56. if( commandParameters != null )
  57. {
  58. foreach (SqlParameter p in commandParameters)
  59. {
  60. if( p != null )
  61. {
  62. // Check for derived output value with no value assigned
  63. if ( ( p.Direction == ParameterDirection.InputOutput || 
  64. p.Direction == ParameterDirection.Input ) && 
  65. (p.Value == null))
  66. {
  67. p.Value = DBNull.Value;
  68. }
  69. command.Parameters.Add(p);
  70. }
  71. }
  72. }
  73.         }
  74.         /// <summary>
  75.         /// This method assigns dataRow column values to an array of SqlParameters
  76.         /// </summary>
  77.         /// <param name="commandParameters">Array of SqlParameters to be assigned values</param>
  78.         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values</param>
  79.         private static void AssignParameterValues(SqlParameter[] commandParameters, DataRow dataRow)
  80.         {
  81.             if ((commandParameters == null) || (dataRow == null)) 
  82.             {
  83.                 // Do nothing if we get no data
  84.                 return;
  85.             }
  86. int i = 0;
  87.             // Set the parameters values
  88.             foreach(SqlParameter commandParameter in commandParameters)
  89.             {
  90. // Check the parameter name
  91. if( commandParameter.ParameterName == null || 
  92. commandParameter.ParameterName.Length <= 1 )
  93. throw new Exception( 
  94. string.Format( 
  95. "Please provide a valid parameter name on the parameter #{0}, the ParameterName property has the following value: '{1}'.", 
  96. i, commandParameter.ParameterName ) );
  97.                 if (dataRow.Table.Columns.IndexOf(commandParameter.ParameterName.Substring(1)) != -1)
  98.                     commandParameter.Value = dataRow[commandParameter.ParameterName.Substring(1)];
  99. i++;
  100.             }
  101.         }
  102.         /// <summary>
  103.         /// This method assigns an array of values to an array of SqlParameters
  104.         /// </summary>
  105.         /// <param name="commandParameters">Array of SqlParameters to be assigned values</param>
  106.         /// <param name="parameterValues">Array of objects holding the values to be assigned</param>
  107.         private static void AssignParameterValues(SqlParameter[] commandParameters, object[] parameterValues)
  108.         {
  109.             if ((commandParameters == null) || (parameterValues == null)) 
  110.             {
  111.                 // Do nothing if we get no data
  112.                 return;
  113.             }
  114.             // We must have the same number of values as we pave parameters to put them in
  115.             if (commandParameters.Length != parameterValues.Length)
  116.             {
  117.                 throw new ArgumentException("Parameter count does not match Parameter Value count.");
  118.             }
  119.             // Iterate through the SqlParameters, assigning the values from the corresponding position in the 
  120.             // value array
  121.             for (int i = 0, j = commandParameters.Length; i < j; i++)
  122.             {
  123.                 // If the current array value derives from IDbDataParameter, then assign its Value property
  124. if (parameterValues[i] is IDbDataParameter)
  125. {
  126. IDbDataParameter paramInstance = (IDbDataParameter)parameterValues[i];
  127. if( paramInstance.Value == null )
  128. {
  129. commandParameters[i].Value = DBNull.Value; 
  130. }
  131. else
  132. {
  133. commandParameters[i].Value = paramInstance.Value;
  134. }
  135. }
  136. else if (parameterValues[i] == null)
  137. {
  138. commandParameters[i].Value = DBNull.Value;
  139. }
  140. else
  141. {
  142. commandParameters[i].Value = parameterValues[i];
  143. }
  144.             }
  145.         }
  146.         /// <summary>
  147.         /// This method opens (if necessary) and assigns a connection, transaction, command type and parameters 
  148.         /// to the provided command
  149.         /// </summary>
  150.         /// <param name="command">The SqlCommand to be prepared</param>
  151.         /// <param name="connection">A valid SqlConnection, on which to execute this command</param>
  152.         /// <param name="transaction">A valid SqlTransaction, or 'null'</param>
  153.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  154.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  155.         /// <param name="commandParameters">An array of SqlParameters to be associated with the command or 'null' if no parameters are required</param>
  156.         /// <param name="mustCloseConnection"><c>true</c> if the connection was opened by the method, otherwose is false.</param>
  157.         private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, out bool mustCloseConnection )
  158.         {
  159. if( command == null ) throw new ArgumentNullException( "command" );
  160. if( commandText == null || commandText.Length == 0 ) throw new ArgumentNullException( "commandText" );
  161.             // If the provided connection is not open, we will open it
  162. if (connection.State != ConnectionState.Open)
  163. {
  164. mustCloseConnection = true;
  165. connection.Open();
  166. }
  167. else
  168. {
  169. mustCloseConnection = false;
  170. }
  171.             // Associate the connection with the command
  172.             command.Connection = connection;
  173.             // Set the command text (stored procedure name or SQL statement)
  174.             command.CommandText = commandText;
  175.             // If we were provided a transaction, assign it
  176.             if (transaction != null)
  177.             {
  178. if( transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
  179.                 command.Transaction = transaction;
  180.             }
  181.             // Set the command type
  182.             command.CommandType = commandType;
  183.             // Attach the command parameters if they are provided
  184.             if (commandParameters != null)
  185.             {
  186.                 AttachParameters(command, commandParameters);
  187.             }
  188.             return;
  189.         }
  190.         #endregion private utility methods & constructors
  191.         #region ExecuteNonQuery
  192.         /// <summary>
  193.         /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the database specified in 
  194.         /// the connection string
  195.         /// </summary>
  196.         /// <remarks>
  197.         /// e.g.:  
  198.         ///  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders");
  199.         /// </remarks>
  200.         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
  201.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  202.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  203.         /// <returns>An int representing the number of rows affected by the command</returns>
  204.         public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText)
  205.         {
  206.             // Pass through the call providing null for the set of SqlParameters
  207.             return ExecuteNonQuery(connectionString, commandType, commandText, (SqlParameter[])null);
  208.         }
  209.         /// <summary>
  210.         /// Execute a SqlCommand (that returns no resultset) against the database specified in the connection string 
  211.         /// using the provided parameters
  212.         /// </summary>
  213.         /// <remarks>
  214.         /// e.g.:  
  215.         ///  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
  216.         /// </remarks>
  217.         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
  218.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  219.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  220.         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
  221.         /// <returns>An int representing the number of rows affected by the command</returns>
  222.         public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  223.         {
  224. if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
  225.             // Create & open a SqlConnection, and dispose of it after we are done
  226.             using (SqlConnection connection = new SqlConnection(connectionString))
  227.             {
  228.                 connection.Open();
  229.                 // Call the overload that takes a connection in place of the connection string
  230.                 return ExecuteNonQuery(connection, commandType, commandText, commandParameters);
  231.             }
  232.         }
  233.         /// <summary>
  234.         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the database specified in 
  235.         /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
  236.         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  237.         /// </summary>
  238.         /// <remarks>
  239.         /// This method provides no access to output parameters or the stored procedure's return value parameter.
  240.         /// 
  241.         /// e.g.:  
  242.         ///  int result = ExecuteNonQuery(connString, "PublishOrders", 24, 36);
  243.         /// </remarks>
  244.         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
  245.         /// <param name="spName">The name of the stored prcedure</param>
  246.         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
  247.         /// <returns>An int representing the number of rows affected by the command</returns>
  248.         public static int ExecuteNonQuery(string connectionString, string spName, params object[] parameterValues)
  249.         {
  250. if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
  251. if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
  252.             // If we receive parameter values, we need to figure out where they go
  253.             if ((parameterValues != null) && (parameterValues.Length > 0)) 
  254.             {
  255.                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
  256.                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
  257.                 // Assign the provided values to these parameters based on parameter order
  258.                 AssignParameterValues(commandParameters, parameterValues);
  259.                 // Call the overload that takes an array of SqlParameters
  260.                 return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters);
  261.             }
  262.             else 
  263.             {
  264. // Otherwise we can just call the SP without params
  265.                 return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName);
  266.             }
  267.         }
  268.         /// <summary>
  269.         /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the provided SqlConnection. 
  270.         /// </summary>
  271.         /// <remarks>
  272.         /// e.g.:  
  273.         ///  int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders");
  274.         /// </remarks>
  275.         /// <param name="connection">A valid SqlConnection</param>
  276.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  277.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  278.         /// <returns>An int representing the number of rows affected by the command</returns>
  279.         public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText)
  280.         {
  281.             // Pass through the call providing null for the set of SqlParameters
  282.             return ExecuteNonQuery(connection, commandType, commandText, (SqlParameter[])null);
  283.         }
  284.         /// <summary>
  285.         /// Execute a SqlCommand (that returns no resultset) against the specified SqlConnection 
  286.         /// using the provided parameters.
  287.         /// </summary>
  288.         /// <remarks>
  289.         /// e.g.:  
  290.         ///  int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
  291.         /// </remarks>
  292.         /// <param name="connection">A valid SqlConnection</param>
  293.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  294.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  295.         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
  296.         /// <returns>An int representing the number of rows affected by the command</returns>
  297.         public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  298.         {
  299. if( connection == null ) throw new ArgumentNullException( "connection" );
  300.             // Create a command and prepare it for execution
  301.             SqlCommand cmd = new SqlCommand();
  302. bool mustCloseConnection = false;
  303.             PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection );
  304.     
  305.             // Finally, execute the command
  306.             int retval = cmd.ExecuteNonQuery();
  307.     
  308.             // Detach the SqlParameters from the command object, so they can be used again
  309.             cmd.Parameters.Clear();
  310. if( mustCloseConnection )
  311. connection.Close();
  312.             return retval;
  313.         }
  314.         /// <summary>
  315.         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified SqlConnection 
  316.         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
  317.         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  318.         /// </summary>
  319.         /// <remarks>
  320.         /// This method provides no access to output parameters or the stored procedure's return value parameter.
  321.         /// 
  322.         /// e.g.:  
  323.         ///  int result = ExecuteNonQuery(conn, "PublishOrders", 24, 36);
  324.         /// </remarks>
  325.         /// <param name="connection">A valid SqlConnection</param>
  326.         /// <param name="spName">The name of the stored procedure</param>
  327.         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
  328.         /// <returns>An int representing the number of rows affected by the command</returns>
  329.         public static int ExecuteNonQuery(SqlConnection connection, string spName, params object[] parameterValues)
  330.         {
  331. if( connection == null ) throw new ArgumentNullException( "connection" );
  332. if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
  333.             // If we receive parameter values, we need to figure out where they go
  334.             if ((parameterValues != null) && (parameterValues.Length > 0)) 
  335.             {
  336.                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
  337.                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
  338.                 // Assign the provided values to these parameters based on parameter order
  339.                 AssignParameterValues(commandParameters, parameterValues);
  340.                 // Call the overload that takes an array of SqlParameters
  341.                 return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName, commandParameters);
  342.             }
  343.             else 
  344.             {
  345. // Otherwise we can just call the SP without params
  346.                 return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName);
  347.             }
  348.         }
  349.         /// <summary>
  350.         /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the provided SqlTransaction. 
  351.         /// </summary>
  352.         /// <remarks>
  353.         /// e.g.:  
  354.         ///  int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "PublishOrders");
  355.         /// </remarks>
  356.         /// <param name="transaction">A valid SqlTransaction</param>
  357.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  358.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  359.         /// <returns>An int representing the number of rows affected by the command</returns>
  360.         public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText)
  361.         {
  362.             // Pass through the call providing null for the set of SqlParameters
  363.             return ExecuteNonQuery(transaction, commandType, commandText, (SqlParameter[])null);
  364.         }
  365.         /// <summary>
  366.         /// Execute a SqlCommand (that returns no resultset) against the specified SqlTransaction
  367.         /// using the provided parameters.
  368.         /// </summary>
  369.         /// <remarks>
  370.         /// e.g.:  
  371.         ///  int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
  372.         /// </remarks>
  373.         /// <param name="transaction">A valid SqlTransaction</param>
  374.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  375.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  376.         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
  377.         /// <returns>An int representing the number of rows affected by the command</returns>
  378. public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  379. {
  380. if( transaction == null ) throw new ArgumentNullException( "transaction" );
  381. if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
  382. // Create a command and prepare it for execution
  383. SqlCommand cmd = new SqlCommand();
  384. bool mustCloseConnection = false;
  385. PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection );
  386.     
  387. // Finally, execute the command
  388. int retval = cmd.ExecuteNonQuery();
  389.     
  390. // Detach the SqlParameters from the command object, so they can be used again
  391. cmd.Parameters.Clear();
  392. return retval;
  393. }
  394.         /// <summary>
  395.         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified 
  396.         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
  397.         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  398.         /// </summary>
  399.         /// <remarks>
  400.         /// This method provides no access to output parameters or the stored procedure's return value parameter.
  401.         /// 
  402.         /// e.g.:  
  403.         ///  int result = ExecuteNonQuery(conn, trans, "PublishOrders", 24, 36);
  404.         /// </remarks>
  405.         /// <param name="transaction">A valid SqlTransaction</param>
  406.         /// <param name="spName">The name of the stored procedure</param>
  407.         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
  408.         /// <returns>An int representing the number of rows affected by the command</returns>
  409.         public static int ExecuteNonQuery(SqlTransaction transaction, string spName, params object[] parameterValues)
  410.         {
  411. if( transaction == null ) throw new ArgumentNullException( "transaction" );
  412. if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
  413. if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
  414. // If we receive parameter values, we need to figure out where they go
  415.             if ((parameterValues != null) && (parameterValues.Length > 0)) 
  416.             {
  417.                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
  418.                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
  419.                 // Assign the provided values to these parameters based on parameter order
  420.                 AssignParameterValues(commandParameters, parameterValues);
  421.                 // Call the overload that takes an array of SqlParameters
  422.                 return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName, commandParameters);
  423.             }
  424.             else 
  425.             {
  426. // Otherwise we can just call the SP without params
  427.                 return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName);
  428.             }
  429.         }
  430.         #endregion ExecuteNonQuery
  431.         #region ExecuteDataset
  432.         /// <summary>
  433.         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in 
  434.         /// the connection string. 
  435.         /// </summary>
  436.         /// <remarks>
  437.         /// e.g.:  
  438.         ///  DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders");
  439.         /// </remarks>
  440.         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
  441.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  442.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  443.         /// <returns>A dataset containing the resultset generated by the command</returns>
  444.         public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText)
  445.         {
  446.             // Pass through the call providing null for the set of SqlParameters
  447.             return ExecuteDataset(connectionString, commandType, commandText, (SqlParameter[])null);
  448.         }
  449.         /// <summary>
  450.         /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string 
  451.         /// using the provided parameters.
  452.         /// </summary>
  453.         /// <remarks>
  454.         /// e.g.:  
  455.         ///  DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
  456.         /// </remarks>
  457.         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
  458.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  459.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  460.         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
  461.         /// <returns>A dataset containing the resultset generated by the command</returns>
  462.         public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  463.         {
  464. if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
  465.             // Create & open a SqlConnection, and dispose of it after we are done
  466.             using (SqlConnection connection = new SqlConnection(connectionString))
  467.             {
  468.                 connection.Open();
  469.                 // Call the overload that takes a connection in place of the connection string
  470.                 return ExecuteDataset(connection, commandType, commandText, commandParameters);
  471.             }
  472.         }
  473.         /// <summary>
  474.         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 
  475.         /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
  476.         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  477.         /// </summary>
  478.         /// <remarks>
  479.         /// This method provides no access to output parameters or the stored procedure's return value parameter.
  480.         /// 
  481.         /// e.g.:  
  482.         ///  DataSet ds = ExecuteDataset(connString, "GetOrders", 24, 36);
  483.         /// </remarks>
  484.         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
  485.         /// <param name="spName">The name of the stored procedure</param>
  486.         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
  487.         /// <returns>A dataset containing the resultset generated by the command</returns>
  488.         public static DataSet ExecuteDataset(string connectionString, string spName, params object[] parameterValues)
  489.         {
  490. if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
  491. if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
  492. // If we receive parameter values, we need to figure out where they go
  493.             if ((parameterValues != null) && (parameterValues.Length > 0)) 
  494.             {
  495.                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
  496.                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
  497.                 // Assign the provided values to these parameters based on parameter order
  498.                 AssignParameterValues(commandParameters, parameterValues);
  499.                 // Call the overload that takes an array of SqlParameters
  500.                 return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName, commandParameters);
  501.             }
  502.             else 
  503.             {
  504. // Otherwise we can just call the SP without params
  505.                 return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName);
  506.             }
  507.         }
  508.         /// <summary>
  509.         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. 
  510.         /// </summary>
  511.         /// <remarks>
  512.         /// e.g.:  
  513.         ///  DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders");
  514.         /// </remarks>
  515.         /// <param name="connection">A valid SqlConnection</param>
  516.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  517.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  518.         /// <returns>A dataset containing the resultset generated by the command</returns>
  519.         public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText)
  520.         {
  521.             // Pass through the call providing null for the set of SqlParameters
  522.             return ExecuteDataset(connection, commandType, commandText, (SqlParameter[])null);
  523.         }
  524.         /// <summary>
  525.         /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 
  526.         /// using the provided parameters.
  527.         /// </summary>
  528.         /// <remarks>
  529.         /// e.g.:  
  530.         ///  DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
  531.         /// </remarks>
  532.         /// <param name="connection">A valid SqlConnection</param>
  533.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  534.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  535.         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
  536.         /// <returns>A dataset containing the resultset generated by the command</returns>
  537. public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  538. {
  539. if( connection == null ) throw new ArgumentNullException( "connection" );
  540. // Create a command and prepare it for execution
  541. SqlCommand cmd = new SqlCommand();
  542. bool mustCloseConnection = false;
  543. PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection );
  544.     
  545. // Create the DataAdapter & DataSet
  546. using( SqlDataAdapter da = new SqlDataAdapter(cmd) )
  547. {
  548. DataSet ds = new DataSet();
  549. // Fill the DataSet using default values for DataTable names, etc
  550. da.Fill(ds);
  551. // Detach the SqlParameters from the command object, so they can be used again
  552. cmd.Parameters.Clear();
  553. if( mustCloseConnection )
  554. connection.Close();
  555. // Return the dataset
  556. return ds;
  557. }
  558. }
  559.         /// <summary>
  560.         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
  561.         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
  562.         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  563.         /// </summary>
  564.         /// <remarks>
  565.         /// This method provides no access to output parameters or the stored procedure's return value parameter.
  566.         /// 
  567.         /// e.g.:  
  568.         ///  DataSet ds = ExecuteDataset(conn, "GetOrders", 24, 36);
  569.         /// </remarks>
  570.         /// <param name="connection">A valid SqlConnection</param>
  571.         /// <param name="spName">The name of the stored procedure</param>
  572.         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
  573.         /// <returns>A dataset containing the resultset generated by the command</returns>
  574.         public static DataSet ExecuteDataset(SqlConnection connection, string spName, params object[] parameterValues)
  575.         {
  576. if( connection == null ) throw new ArgumentNullException( "connection" );
  577. if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
  578.             // If we receive parameter values, we need to figure out where they go
  579.             if ((parameterValues != null) && (parameterValues.Length > 0)) 
  580.             {
  581.                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
  582.                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
  583.                 // Assign the provided values to these parameters based on parameter order
  584.                 AssignParameterValues(commandParameters, parameterValues);
  585.                 // Call the overload that takes an array of SqlParameters
  586.                 return ExecuteDataset(connection, CommandType.StoredProcedure, spName, commandParameters);
  587.             }
  588.             else 
  589.             {
  590. // Otherwise we can just call the SP without params
  591.                 return ExecuteDataset(connection, CommandType.StoredProcedure, spName);
  592.             }
  593.         }
  594.         /// <summary>
  595.         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. 
  596.         /// </summary>
  597.         /// <remarks>
  598.         /// e.g.:  
  599.         ///  DataSet ds = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders");
  600.         /// </remarks>
  601.         /// <param name="transaction">A valid SqlTransaction</param>
  602.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  603.         /// <param name="commandText">The stored procedure name or T-SQL 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)
  606.         {
  607.             // Pass through the call providing null for the set of SqlParameters
  608.             return ExecuteDataset(transaction, commandType, commandText, (SqlParameter[])null);
  609.         }
  610.         /// <summary>
  611.         /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction
  612.         /// using the provided parameters.
  613.         /// </summary>
  614.         /// <remarks>
  615.         /// e.g.:  
  616.         ///  DataSet ds = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
  617.         /// </remarks>
  618.         /// <param name="transaction">A valid SqlTransaction</param>
  619.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  620.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  621.         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
  622.         /// <returns>A dataset containing the resultset generated by the command</returns>
  623. public static DataSet ExecuteDataset(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  624. {
  625. if( transaction == null ) throw new ArgumentNullException( "transaction" );
  626. if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
  627. // Create a command and prepare it for execution
  628. SqlCommand cmd = new SqlCommand();
  629. bool mustCloseConnection = false;
  630. PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection );
  631.     
  632. // Create the DataAdapter & DataSet
  633. using( SqlDataAdapter da = new SqlDataAdapter(cmd) )
  634. {
  635. DataSet ds = new DataSet();
  636. // Fill the DataSet using default values for DataTable names, etc
  637. da.Fill(ds);
  638.     
  639. // Detach the SqlParameters from the command object, so they can be used again
  640. cmd.Parameters.Clear();
  641. // Return the dataset
  642. return ds;
  643. }
  644. }
  645.         /// <summary>
  646.         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified 
  647.         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
  648.         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  649.         /// </summary>
  650.         /// <remarks>
  651.         /// This method provides no access to output parameters or the stored procedure's return value parameter.
  652.         /// 
  653.         /// e.g.:  
  654.         ///  DataSet ds = ExecuteDataset(trans, "GetOrders", 24, 36);
  655.         /// </remarks>
  656.         /// <param name="transaction">A valid SqlTransaction</param>
  657.         /// <param name="spName">The name of the stored procedure</param>
  658.         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
  659.         /// <returns>A dataset containing the resultset generated by the command</returns>
  660.         public static DataSet ExecuteDataset(SqlTransaction transaction, string spName, params object[] parameterValues)
  661.         {
  662. if( transaction == null ) throw new ArgumentNullException( "transaction" );
  663. if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
  664. if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
  665. // If we receive parameter values, we need to figure out where they go
  666.             if ((parameterValues != null) && (parameterValues.Length > 0)) 
  667.             {
  668.                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
  669.                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
  670.                 // Assign the provided values to these parameters based on parameter order
  671.                 AssignParameterValues(commandParameters, parameterValues);
  672.                 // Call the overload that takes an array of SqlParameters
  673.                 return ExecuteDataset(transaction, CommandType.StoredProcedure, spName, commandParameters);
  674.             }
  675.             else 
  676.             {
  677. // Otherwise we can just call the SP without params
  678.                 return ExecuteDataset(transaction, CommandType.StoredProcedure, spName);
  679.             }
  680.         }
  681.         #endregion ExecuteDataset
  682.         #region ExecuteReader
  683.         /// <summary>
  684.         /// This enum is used to indicate whether the connection was provided by the caller, or created by SqlHelper, so that
  685.         /// we can set the appropriate CommandBehavior when calling ExecuteReader()
  686.         /// </summary>
  687.         private enum SqlConnectionOwnership
  688.         {
  689.             /// <summary>Connection is owned and managed by SqlHelper</summary>
  690.             Internal, 
  691.             /// <summary>Connection is owned and managed by the caller</summary>
  692.             External
  693.         }
  694.         /// <summary>
  695.         /// Create and prepare a SqlCommand, and call ExecuteReader with the appropriate CommandBehavior.
  696.         /// </summary>
  697.         /// <remarks>
  698.         /// If we created and opened the connection, we want the connection to be closed when the DataReader is closed.
  699.         /// 
  700.         /// If the caller provided the connection, we want to leave it to them to manage.
  701.         /// </remarks>
  702.         /// <param name="connection">A valid SqlConnection, on which to execute this command</param>
  703.         /// <param name="transaction">A valid SqlTransaction, or 'null'</param>
  704.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  705.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  706.         /// <param name="commandParameters">An array of SqlParameters to be associated with the command or 'null' if no parameters are required</param>
  707.         /// <param name="connectionOwnership">Indicates whether the connection parameter was provided by the caller, or created by SqlHelper</param>
  708.         /// <returns>SqlDataReader containing the results of the command</returns>
  709.         private static SqlDataReader ExecuteReader(SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, SqlConnectionOwnership connectionOwnership)
  710.         {
  711. if( connection == null ) throw new ArgumentNullException( "connection" );
  712. bool mustCloseConnection = false;
  713.             // Create a command and prepare it for execution
  714.             SqlCommand cmd = new SqlCommand();
  715. try
  716. {
  717. PrepareCommand(cmd, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection );
  718. // Create a reader
  719. SqlDataReader dataReader;
  720. // Call ExecuteReader with the appropriate CommandBehavior
  721. if (connectionOwnership == SqlConnectionOwnership.External)
  722. {
  723. dataReader = cmd.ExecuteReader();
  724. }
  725. else
  726. {
  727. dataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
  728. }
  729. // Detach the SqlParameters from the command object, so they can be used again.
  730. // HACK: There is a problem here, the output parameter values are fletched 
  731. // when the reader is closed, so if the parameters are detached from the command
  732. // then the SqlReader can磘 set its values. 
  733. // When this happen, the parameters can磘 be used again in other command.
  734. bool canClear = true;
  735. foreach(SqlParameter commandParameter in cmd.Parameters)
  736. {
  737. if (commandParameter.Direction != ParameterDirection.Input)
  738. canClear = false;
  739. }
  740.             
  741. if (canClear)
  742. {
  743. cmd.Parameters.Clear();
  744. }
  745. return dataReader;
  746. }
  747. catch
  748. {
  749. if( mustCloseConnection )
  750. connection.Close();
  751. throw;
  752. }
  753.         }
  754.         /// <summary>
  755.         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in 
  756.         /// the connection string. 
  757.         /// </summary>
  758.         /// <remarks>
  759.         /// e.g.:  
  760.         ///  SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders");
  761.         /// </remarks>
  762.         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
  763.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  764.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  765.         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
  766.         public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText)
  767.         {
  768.             // Pass through the call providing null for the set of SqlParameters
  769.             return ExecuteReader(connectionString, commandType, commandText, (SqlParameter[])null);
  770.         }
  771.         /// <summary>
  772.         /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string 
  773.         /// using the provided parameters.
  774.         /// </summary>
  775.         /// <remarks>
  776.         /// e.g.:  
  777.         ///  SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
  778.         /// </remarks>
  779.         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
  780.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  781.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  782.         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
  783.         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
  784.         public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  785.         {
  786. if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
  787.             SqlConnection connection = null;
  788.             try
  789.             {
  790. connection = new SqlConnection(connectionString);
  791. connection.Open();
  792.                 // Call the private overload that takes an internally owned connection in place of the connection string
  793.                 return ExecuteReader(connection, null, commandType, commandText, commandParameters,SqlConnectionOwnership.Internal);
  794.             }
  795.             catch
  796.             {
  797.                 // If we fail to return the SqlDatReader, we need to close the connection ourselves
  798.                 if( connection != null ) connection.Close();
  799.                 throw;
  800.             }
  801.             
  802.         }
  803.         /// <summary>
  804.         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 
  805.         /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
  806.         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  807.         /// </summary>
  808.         /// <remarks>
  809.         /// This method provides no access to output parameters or the stored procedure's return value parameter.
  810.         /// 
  811.         /// e.g.:  
  812.         ///  SqlDataReader dr = ExecuteReader(connString, "GetOrders", 24, 36);
  813.         /// </remarks>
  814.         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
  815.         /// <param name="spName">The name of the stored procedure</param>
  816.         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
  817.         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
  818.         public static SqlDataReader ExecuteReader(string connectionString, string spName, params object[] parameterValues)
  819.         {
  820. if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
  821. if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
  822. // If we receive parameter values, we need to figure out where they go
  823.             if ((parameterValues != null) && (parameterValues.Length > 0)) 
  824.             {
  825.                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
  826.                 AssignParameterValues(commandParameters, parameterValues);
  827.                 return ExecuteReader(connectionString, CommandType.StoredProcedure, spName, commandParameters);
  828.             }
  829.             else 
  830.             {
  831. // Otherwise we can just call the SP without params
  832.                 return ExecuteReader(connectionString, CommandType.StoredProcedure, spName);
  833.             }
  834.         }
  835.         /// <summary>
  836.         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. 
  837.         /// </summary>
  838.         /// <remarks>
  839.         /// e.g.:  
  840.         ///  SqlDataReader dr = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders");
  841.         /// </remarks>
  842.         /// <param name="connection">A valid SqlConnection</param>
  843.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  844.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  845.         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
  846.         public static SqlDataReader ExecuteReader(SqlConnection connection, CommandType commandType, string commandText)
  847.         {
  848.             // Pass through the call providing null for the set of SqlParameters
  849.             return ExecuteReader(connection, commandType, commandText, (SqlParameter[])null);
  850.         }
  851.         /// <summary>
  852.         /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 
  853.         /// using the provided parameters.
  854.         /// </summary>
  855.         /// <remarks>
  856.         /// e.g.:  
  857.         ///  SqlDataReader dr = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
  858.         /// </remarks>
  859.         /// <param name="connection">A valid SqlConnection</param>
  860.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  861.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  862.         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
  863.         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
  864.         public static SqlDataReader ExecuteReader(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  865.         {
  866.             // Pass through the call to the private overload using a null transaction value and an externally owned connection
  867.             return ExecuteReader(connection, (SqlTransaction)null, commandType, commandText, commandParameters, SqlConnectionOwnership.External);
  868.         }
  869.         /// <summary>
  870.         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
  871.         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
  872.         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  873.         /// </summary>
  874.         /// <remarks>
  875.         /// This method provides no access to output parameters or the stored procedure's return value parameter.
  876.         /// 
  877.         /// e.g.:  
  878.         ///  SqlDataReader dr = ExecuteReader(conn, "GetOrders", 24, 36);
  879.         /// </remarks>
  880.         /// <param name="connection">A valid SqlConnection</param>
  881.         /// <param name="spName">The name of the stored procedure</param>
  882.         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
  883.         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
  884.         public static SqlDataReader ExecuteReader(SqlConnection connection, string spName, params object[] parameterValues)
  885.         {
  886. if( connection == null ) throw new ArgumentNullException( "connection" );
  887. if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
  888.             // If we receive parameter values, we need to figure out where they go
  889.             if ((parameterValues != null) && (parameterValues.Length > 0)) 
  890.             {
  891.                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
  892.                 AssignParameterValues(commandParameters, parameterValues);
  893.                 return ExecuteReader(connection, CommandType.StoredProcedure, spName, commandParameters);
  894.             }
  895.             else 
  896.             {
  897. // Otherwise we can just call the SP without params
  898.                 return ExecuteReader(connection, CommandType.StoredProcedure, spName);
  899.             }
  900.         }
  901.         /// <summary>
  902.         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. 
  903.         /// </summary>
  904.         /// <remarks>
  905.         /// e.g.:  
  906.         ///  SqlDataReader dr = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders");
  907.         /// </remarks>
  908.         /// <param name="transaction">A valid SqlTransaction</param>
  909.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  910.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  911.         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
  912.         public static SqlDataReader ExecuteReader(SqlTransaction transaction, CommandType commandType, string commandText)
  913.         {
  914.             // Pass through the call providing null for the set of SqlParameters
  915.             return ExecuteReader(transaction, commandType, commandText, (SqlParameter[])null);
  916.         }
  917.         /// <summary>
  918.         /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction
  919.         /// using the provided parameters.
  920.         /// </summary>
  921.         /// <remarks>
  922.         /// e.g.:  
  923.         ///   SqlDataReader dr = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
  924.         /// </remarks>
  925.         /// <param name="transaction">A valid SqlTransaction</param>
  926.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  927.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  928.         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
  929.         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
  930.         public static SqlDataReader ExecuteReader(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  931.         {
  932. if( transaction == null ) throw new ArgumentNullException( "transaction" );
  933. if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
  934. // Pass through to private overload, indicating that the connection is owned by the caller
  935.             return ExecuteReader(transaction.Connection, transaction, commandType, commandText, commandParameters, SqlConnectionOwnership.External);
  936.         }
  937.         /// <summary>
  938.         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified
  939.         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
  940.         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  941.         /// </summary>
  942.         /// <remarks>
  943.         /// This method provides no access to output parameters or the stored procedure's return value parameter.
  944.         /// 
  945.         /// e.g.:  
  946.         ///  SqlDataReader dr = ExecuteReader(trans, "GetOrders", 24, 36);
  947.         /// </remarks>
  948.         /// <param name="transaction">A valid SqlTransaction</param>
  949.         /// <param name="spName">The name of the stored procedure</param>
  950.         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
  951.         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
  952.         public static SqlDataReader ExecuteReader(SqlTransaction transaction, string spName, params object[] parameterValues)
  953.         {
  954. if( transaction == null ) throw new ArgumentNullException( "transaction" );
  955. if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
  956. if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
  957.             // If we receive parameter values, we need to figure out where they go
  958.             if ((parameterValues != null) && (parameterValues.Length > 0)) 
  959.             {
  960.                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
  961.                 AssignParameterValues(commandParameters, parameterValues);
  962.                 return ExecuteReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
  963.             }
  964.             else 
  965.             {
  966. // Otherwise we can just call the SP without params
  967.                 return ExecuteReader(transaction, CommandType.StoredProcedure, spName);
  968.             }
  969.         }
  970.         #endregion ExecuteReader
  971.         #region ExecuteScalar
  972.         /// <summary>
  973.         /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the database specified in 
  974.         /// the connection string. 
  975.         /// </summary>
  976.         /// <remarks>
  977.         /// e.g.:  
  978.         ///  int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount");
  979.         /// </remarks>
  980.         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
  981.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  982.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  983.         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
  984.         public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText)
  985.         {
  986.             // Pass through the call providing null for the set of SqlParameters
  987.             return ExecuteScalar(connectionString, commandType, commandText, (SqlParameter[])null);
  988.         }
  989.         /// <summary>
  990.         /// Execute a SqlCommand (that returns a 1x1 resultset) against the database specified in the connection string 
  991.         /// using the provided parameters.
  992.         /// </summary>
  993.         /// <remarks>
  994.         /// e.g.:  
  995.         ///  int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));
  996.         /// </remarks>
  997.         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
  998.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  999.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  1000.         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
  1001.         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
  1002.         public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  1003.         {
  1004. if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
  1005.             // Create & open a SqlConnection, and dispose of it after we are done
  1006.             using (SqlConnection connection = new SqlConnection(connectionString))
  1007.             {
  1008.                 connection.Open();
  1009.                 // Call the overload that takes a connection in place of the connection string
  1010.                 return ExecuteScalar(connection, commandType, commandText, commandParameters);
  1011.             }
  1012.         }
  1013.         /// <summary>
  1014.         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the database specified in 
  1015.         /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
  1016.         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  1017.         /// </summary>
  1018.         /// <remarks>
  1019.         /// This method provides no access to output parameters or the stored procedure's return value parameter.
  1020.         /// 
  1021.         /// e.g.:  
  1022.         ///  int orderCount = (int)ExecuteScalar(connString, "GetOrderCount", 24, 36);
  1023.         /// </remarks>
  1024.         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
  1025.         /// <param name="spName">The name of the stored procedure</param>
  1026.         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
  1027.         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
  1028.         public static object ExecuteScalar(string connectionString, string spName, params object[] parameterValues)
  1029.         {
  1030. if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
  1031. if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
  1032. // If we receive parameter values, we need to figure out where they go
  1033.             if ((parameterValues != null) && (parameterValues.Length > 0)) 
  1034.             {
  1035.                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
  1036.                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
  1037.                 // Assign the provided values to these parameters based on parameter order
  1038.                 AssignParameterValues(commandParameters, parameterValues);
  1039.                 // Call the overload that takes an array of SqlParameters
  1040.                 return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName, commandParameters);
  1041.             }
  1042.             else 
  1043.             {
  1044. // Otherwise we can just call the SP without params
  1045.                 return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName);
  1046.             }
  1047.         }
  1048.         /// <summary>
  1049.         /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the provided SqlConnection. 
  1050.         /// </summary>
  1051.         /// <remarks>
  1052.         /// e.g.:  
  1053.         ///  int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount");
  1054.         /// </remarks>
  1055.         /// <param name="connection">A valid SqlConnection</param>
  1056.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  1057.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  1058.         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
  1059.         public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText)
  1060.         {
  1061.             // Pass through the call providing null for the set of SqlParameters
  1062.             return ExecuteScalar(connection, commandType, commandText, (SqlParameter[])null);
  1063.         }
  1064.         /// <summary>
  1065.         /// Execute a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection 
  1066.         /// using the provided parameters.
  1067.         /// </summary>
  1068.         /// <remarks>
  1069.         /// e.g.:  
  1070.         ///  int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));
  1071.         /// </remarks>
  1072.         /// <param name="connection">A valid SqlConnection</param>
  1073.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  1074.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  1075.         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
  1076.         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
  1077. public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  1078. {
  1079. if( connection == null ) throw new ArgumentNullException( "connection" );
  1080. // Create a command and prepare it for execution
  1081. SqlCommand cmd = new SqlCommand();
  1082. bool mustCloseConnection = false;
  1083. PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection );
  1084.     
  1085. // Execute the command & return the results
  1086. object retval = cmd.ExecuteScalar();
  1087.     
  1088. // Detach the SqlParameters from the command object, so they can be used again
  1089. cmd.Parameters.Clear();
  1090. if( mustCloseConnection )
  1091. connection.Close();
  1092. return retval;
  1093. }
  1094.         /// <summary>
  1095.         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection 
  1096.         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
  1097.         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  1098.         /// </summary>
  1099.         /// <remarks>
  1100.         /// This method provides no access to output parameters or the stored procedure's return value parameter.
  1101.         /// 
  1102.         /// e.g.:  
  1103.         ///  int orderCount = (int)ExecuteScalar(conn, "GetOrderCount", 24, 36);
  1104.         /// </remarks>
  1105.         /// <param name="connection">A valid SqlConnection</param>
  1106.         /// <param name="spName">The name of the stored procedure</param>
  1107.         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
  1108.         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
  1109.         public static object ExecuteScalar(SqlConnection connection, string spName, params object[] parameterValues)
  1110.         {
  1111. if( connection == null ) throw new ArgumentNullException( "connection" );
  1112. if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
  1113.             // If we receive parameter values, we need to figure out where they go
  1114.             if ((parameterValues != null) && (parameterValues.Length > 0)) 
  1115.             {
  1116.                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
  1117.                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
  1118.                 // Assign the provided values to these parameters based on parameter order
  1119.                 AssignParameterValues(commandParameters, parameterValues);
  1120.                 // Call the overload that takes an array of SqlParameters
  1121.                 return ExecuteScalar(connection, CommandType.StoredProcedure, spName, commandParameters);
  1122.             }
  1123.             else 
  1124.             {
  1125. // Otherwise we can just call the SP without params
  1126.                 return ExecuteScalar(connection, CommandType.StoredProcedure, spName);
  1127.             }
  1128.         }
  1129.         /// <summary>
  1130.         /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the provided SqlTransaction. 
  1131.         /// </summary>
  1132.         /// <remarks>
  1133.         /// e.g.:  
  1134.         ///  int orderCount = (int)ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount");
  1135.         /// </remarks>
  1136.         /// <param name="transaction">A valid SqlTransaction</param>
  1137.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  1138.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  1139.         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
  1140.         public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText)
  1141.         {
  1142.             // Pass through the call providing null for the set of SqlParameters
  1143.             return ExecuteScalar(transaction, commandType, commandText, (SqlParameter[])null);
  1144.         }
  1145.         /// <summary>
  1146.         /// Execute a SqlCommand (that returns a 1x1 resultset) against the specified SqlTransaction
  1147.         /// using the provided parameters.
  1148.         /// </summary>
  1149.         /// <remarks>
  1150.         /// e.g.:  
  1151.         ///  int orderCount = (int)ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));
  1152.         /// </remarks>
  1153.         /// <param name="transaction">A valid SqlTransaction</param>
  1154.         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
  1155.         /// <param name="commandText">The stored procedure name or T-SQL command</param>
  1156.         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
  1157.         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
  1158. public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  1159. {
  1160. if( transaction == null ) throw new ArgumentNullException( "transaction" );
  1161. if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
  1162. // Create a command and prepare it for execution
  1163. SqlCommand cmd = new SqlCommand();
  1164. bool mustCloseConnection = false;
  1165. PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection );
  1166.     
  1167. // Execute the command & return the results
  1168. object retval = cmd.ExecuteScalar();
  1169.     
  1170. // Detach the SqlParameters from the command object, so they can be used again
  1171. cmd.Parameters.Clear();
  1172. return retval;
  1173. }
  1174.         /// <summary>
  1175.         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified
  1176.         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
  1177.         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  1178.         /// </summary>
  1179.         /// <remarks>
  1180.         /// This method provides no access to output parameters or the stored procedure's return value parameter.
  1181.         /// 
  1182.         /// e.g.:  
  1183.         ///  int orderCount = (int)ExecuteScalar(trans, "GetOrderCount", 24, 36);
  1184.         /// </remarks>
  1185.         /// <param name="transaction">A valid SqlTransaction</param>