SqlHelper.cs

   1 // ===============================================================================

   2 // Microsoft Data Access Application Block for .NET

   3 // http://msdn.microsoft.com/library/en-us/dnbda/html/daab-rm.asp

   4 //

   5 // SQLHelper.cs

   6 //

   7 // This file contains the implementations of the SqlHelper and SqlHelperParameterCache

   8 // classes.

   9 //

  10 // For more information see the Data Access Application Block Implementation Overview. 

  11 // ===============================================================================

  12 // Release history

  13 // VERSION    DESCRIPTION

  14 //   2.0    Added support for FillDataset, UpdateDataset and "Param" helper methods

  15 //

  16 // ===============================================================================

  17 // Copyright (C) 2000-2001 Microsoft Corporation

  18 // All rights reserved.

  19 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY

  20 // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT

  21 // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR

  22 // FITNESS FOR A PARTICULAR PURPOSE.

  23 // ==============================================================================

  24 

  25 using System;

  26 using System.Data;

  27 using System.Xml;

  28 using System.Data.SqlClient;

  29 using System.Collections;

  30 

  31 namespace Microsoft.ApplicationBlocks.Data

  32 {

  33   /// <summary>

  34   /// The SqlHelper class is intended to encapsulate high performance, scalable best practices for 

  35   /// common uses of SqlClient

  36   /// </summary>

  37   public sealed class SqlHelper

  38   {

  39     #region private utility methods & constructors

  40 

  41     // Since this class provides only static methods, make the default constructor private to prevent 

  42     // instances from being created with "new SqlHelper()"

  43     private SqlHelper() { }

  44 

  45     /// <summary>

  46     /// This method is used to attach array of SqlParameters to a SqlCommand.

  47     /// 

  48     /// This method will assign a value of DbNull to any parameter with a direction of

  49     /// InputOutput and a value of null.  

  50     /// 

  51     /// This behavior will prevent default values from being used, but

  52     /// this will be the less common case than an intended pure output parameter (derived as InputOutput)

  53     /// where the user provided no input value.

  54     /// </summary>

  55     /// <param name="command">The command to which the parameters will be added</param>

  56     /// <param name="commandParameters">An array of SqlParameters to be added to command</param>

  57     private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters)

  58     {

  59       if (command == null) throw new ArgumentNullException("command");

  60       if (commandParameters != null)

  61       {

  62         foreach (SqlParameter p in commandParameters)

  63         {

  64           if (p != null)

  65           {

  66             // Check for derived output value with no value assigned

  67             if ((p.Direction == ParameterDirection.InputOutput ||

  68               p.Direction == ParameterDirection.Input) &&

  69               (p.Value == null))

  70             {

  71               p.Value = DBNull.Value;

  72             }

  73             command.Parameters.Add(p);

  74           }

  75         }

  76       }

  77     }

  78 

  79     /// <summary>

  80     /// This method assigns dataRow column values to an array of SqlParameters

  81     /// </summary>

  82     /// <param name="commandParameters">Array of SqlParameters to be assigned values</param>

  83     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values</param>

  84     private static void AssignParameterValues(SqlParameter[] commandParameters, DataRow dataRow)

  85     {

  86       if ((commandParameters == null) || (dataRow == null))

  87       {

  88         // Do nothing if we get no data

  89         return;

  90       }

  91 

  92       int i = 0;

  93       // Set the parameters values

  94       foreach (SqlParameter commandParameter in commandParameters)

  95       {

  96         // Check the parameter name

  97         if (commandParameter.ParameterName == null ||

  98           commandParameter.ParameterName.Length <= 1)

  99           throw new Exception(

 100             string.Format(

 101               "Please provide a valid parameter name on the parameter #{0}, the ParameterName property has the following value: '{1}'.",

 102               i, commandParameter.ParameterName));

 103         if (dataRow.Table.Columns.IndexOf(commandParameter.ParameterName.Substring(1)) != -1)

 104           commandParameter.Value = dataRow[commandParameter.ParameterName.Substring(1)];

 105         i++;

 106       }

 107     }

 108 

 109     /// <summary>

 110     /// This method assigns an array of values to an array of SqlParameters

 111     /// </summary>

 112     /// <param name="commandParameters">Array of SqlParameters to be assigned values</param>

 113     /// <param name="parameterValues">Array of objects holding the values to be assigned</param>

 114     private static void AssignParameterValues(SqlParameter[] commandParameters, object[] parameterValues)

 115     {

 116       if ((commandParameters == null) || (parameterValues == null))

 117       {

 118         // Do nothing if we get no data

 119         return;

 120       }

 121 

 122       // We must have the same number of values as we pave parameters to put them in

 123       if (commandParameters.Length != parameterValues.Length)

 124       {

 125         throw new ArgumentException("Parameter count does not match Parameter Value count.");

 126       }

 127 

 128       // Iterate through the SqlParameters, assigning the values from the corresponding position in the 

 129       // value array

 130       for (int i = 0, j = commandParameters.Length; i < j; i++)

 131       {

 132         // If the current array value derives from IDbDataParameter, then assign its Value property

 133         if (parameterValues[i] is IDbDataParameter)

 134         {

 135           IDbDataParameter paramInstance = (IDbDataParameter)parameterValues[i];

 136           if (paramInstance.Value == null)

 137           {

 138             commandParameters[i].Value = DBNull.Value;

 139           }

 140           else

 141           {

 142             commandParameters[i].Value = paramInstance.Value;

 143           }

 144         }

 145         else if (parameterValues[i] == null)

 146         {

 147           commandParameters[i].Value = DBNull.Value;

 148         }

 149         else

 150         {

 151           commandParameters[i].Value = parameterValues[i];

 152         }

 153       }

 154     }

 155 

 156     /// <summary>

 157     /// This method opens (if necessary) and assigns a connection, transaction, command type and parameters 

 158     /// to the provided command

 159     /// </summary>

 160     /// <param name="command">The SqlCommand to be prepared</param>

 161     /// <param name="connection">A valid SqlConnection, on which to execute this command</param>

 162     /// <param name="transaction">A valid SqlTransaction, or 'null'</param>

 163     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 164     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 165     /// <param name="commandParameters">An array of SqlParameters to be associated with the command or 'null' if no parameters are required</param>

 166     /// <param name="mustCloseConnection"><c>true</c> if the connection was opened by the method, otherwose is false.</param>

 167     private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, out bool mustCloseConnection)

 168     {

 169       if (command == null) throw new ArgumentNullException("command");

 170       if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");

 171 

 172       // If the provided connection is not open, we will open it

 173       if (connection.State != ConnectionState.Open)

 174       {

 175         mustCloseConnection = true;

 176         connection.Open();

 177       }

 178       else

 179       {

 180         mustCloseConnection = false;

 181       }

 182 

 183       // Associate the connection with the command

 184       command.Connection = connection;

 185 

 186       // Set the command text (stored procedure name or SQL statement)

 187       command.CommandText = commandText;

 188 

 189       // If we were provided a transaction, assign it

 190       if (transaction != null)

 191       {

 192         if (transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

 193         command.Transaction = transaction;

 194       }

 195 

 196       // Set the command type

 197       command.CommandType = commandType;

 198 

 199       // Attach the command parameters if they are provided

 200       if (commandParameters != null)

 201       {

 202         AttachParameters(command, commandParameters);

 203       }

 204       return;

 205     }

 206 

 207     #endregion private utility methods & constructors

 208 

 209     #region ExecuteNonQuery

 210 

 211     /// <summary>

 212     /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the database specified in 

 213     /// the connection string

 214     /// </summary>

 215     /// <remarks>

 216     /// e.g.:  

 217     ///  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders");

 218     /// </remarks>

 219     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

 220     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 221     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 222     /// <returns>An int representing the number of rows affected by the command</returns>

 223     public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText)

 224     {

 225       // Pass through the call providing null for the set of SqlParameters

 226       return ExecuteNonQuery(connectionString, commandType, commandText, (SqlParameter[])null);

 227     }

 228 

 229     /// <summary>

 230     /// Execute a SqlCommand (that returns no resultset) against the database specified in the connection string 

 231     /// using the provided parameters

 232     /// </summary>

 233     /// <remarks>

 234     /// e.g.:  

 235     ///  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));

 236     /// </remarks>

 237     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

 238     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 239     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 240     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

 241     /// <returns>An int representing the number of rows affected by the command</returns>

 242     public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

 243     {

 244       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

 245 

 246       // Create & open a SqlConnection, and dispose of it after we are done

 247       using (SqlConnection connection = new SqlConnection(connectionString))

 248       {

 249         connection.Open();

 250 

 251         // Call the overload that takes a connection in place of the connection string

 252         return ExecuteNonQuery(connection, commandType, commandText, commandParameters);

 253       }

 254     }

 255 

 256     /// <summary>

 257     /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the database specified in 

 258     /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 

 259     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

 260     /// </summary>

 261     /// <remarks>

 262     /// This method provides no access to output parameters or the stored procedure's return value parameter.

 263     /// 

 264     /// e.g.:  

 265     ///  int result = ExecuteNonQuery(connString, "PublishOrders", 24, 36);

 266     /// </remarks>

 267     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

 268     /// <param name="spName">The name of the stored prcedure</param>

 269     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

 270     /// <returns>An int representing the number of rows affected by the command</returns>

 271     public static int ExecuteNonQuery(string connectionString, string spName, params object[] parameterValues)

 272     {

 273       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

 274       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

 275 

 276       // If we receive parameter values, we need to figure out where they go

 277       if ((parameterValues != null) && (parameterValues.Length > 0))

 278       {

 279         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

 280         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);

 281 

 282         // Assign the provided values to these parameters based on parameter order

 283         AssignParameterValues(commandParameters, parameterValues);

 284 

 285         // Call the overload that takes an array of SqlParameters

 286         return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters);

 287       }

 288       else

 289       {

 290         // Otherwise we can just call the SP without params

 291         return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName);

 292       }

 293     }

 294 

 295     /// <summary>

 296     /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the provided SqlConnection. 

 297     /// </summary>

 298     /// <remarks>

 299     /// e.g.:  

 300     ///  int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders");

 301     /// </remarks>

 302     /// <param name="connection">A valid SqlConnection</param>

 303     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 304     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 305     /// <returns>An int representing the number of rows affected by the command</returns>

 306     public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText)

 307     {

 308       // Pass through the call providing null for the set of SqlParameters

 309       return ExecuteNonQuery(connection, commandType, commandText, (SqlParameter[])null);

 310     }

 311 

 312     /// <summary>

 313     /// Execute a SqlCommand (that returns no resultset) against the specified SqlConnection 

 314     /// using the provided parameters.

 315     /// </summary>

 316     /// <remarks>

 317     /// e.g.:  

 318     ///  int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));

 319     /// </remarks>

 320     /// <param name="connection">A valid SqlConnection</param>

 321     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 322     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 323     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

 324     /// <returns>An int representing the number of rows affected by the command</returns>

 325     public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

 326     {

 327       if (connection == null) throw new ArgumentNullException("connection");

 328 

 329       // Create a command and prepare it for execution

 330       SqlCommand cmd = new SqlCommand();

 331       bool mustCloseConnection = false;

 332       PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);

 333 

 334       // Finally, execute the command

 335       int retval = cmd.ExecuteNonQuery();

 336 

 337       // Detach the SqlParameters from the command object, so they can be used again

 338       cmd.Parameters.Clear();

 339       if (mustCloseConnection)

 340         connection.Close();

 341       return retval;

 342     }

 343 

 344     /// <summary>

 345     /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified SqlConnection 

 346     /// using the provided parameter values.  This method will query the database to discover the parameters for the 

 347     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

 348     /// </summary>

 349     /// <remarks>

 350     /// This method provides no access to output parameters or the stored procedure's return value parameter.

 351     /// 

 352     /// e.g.:  

 353     ///  int result = ExecuteNonQuery(conn, "PublishOrders", 24, 36);

 354     /// </remarks>

 355     /// <param name="connection">A valid SqlConnection</param>

 356     /// <param name="spName">The name of the stored procedure</param>

 357     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

 358     /// <returns>An int representing the number of rows affected by the command</returns>

 359     public static int ExecuteNonQuery(SqlConnection connection, string spName, params object[] parameterValues)

 360     {

 361       if (connection == null) throw new ArgumentNullException("connection");

 362       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

 363 

 364       // If we receive parameter values, we need to figure out where they go

 365       if ((parameterValues != null) && (parameterValues.Length > 0))

 366       {

 367         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

 368         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);

 369 

 370         // Assign the provided values to these parameters based on parameter order

 371         AssignParameterValues(commandParameters, parameterValues);

 372 

 373         // Call the overload that takes an array of SqlParameters

 374         return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName, commandParameters);

 375       }

 376       else

 377       {

 378         // Otherwise we can just call the SP without params

 379         return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName);

 380       }

 381     }

 382 

 383     /// <summary>

 384     /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the provided SqlTransaction. 

 385     /// </summary>

 386     /// <remarks>

 387     /// e.g.:  

 388     ///  int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "PublishOrders");

 389     /// </remarks>

 390     /// <param name="transaction">A valid SqlTransaction</param>

 391     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 392     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 393     /// <returns>An int representing the number of rows affected by the command</returns>

 394     public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText)

 395     {

 396       // Pass through the call providing null for the set of SqlParameters

 397       return ExecuteNonQuery(transaction, commandType, commandText, (SqlParameter[])null);

 398     }

 399 

 400     /// <summary>

 401     /// Execute a SqlCommand (that returns no resultset) against the specified SqlTransaction

 402     /// using the provided parameters.

 403     /// </summary>

 404     /// <remarks>

 405     /// e.g.:  

 406     ///  int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));

 407     /// </remarks>

 408     /// <param name="transaction">A valid SqlTransaction</param>

 409     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 410     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 411     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

 412     /// <returns>An int representing the number of rows affected by the command</returns>

 413     public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

 414     {

 415       if (transaction == null) throw new ArgumentNullException("transaction");

 416       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

 417 

 418       // Create a command and prepare it for execution

 419       SqlCommand cmd = new SqlCommand();

 420       bool mustCloseConnection = false;

 421       PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);

 422 

 423       // Finally, execute the command

 424       int retval = cmd.ExecuteNonQuery();

 425 

 426       // Detach the SqlParameters from the command object, so they can be used again

 427       cmd.Parameters.Clear();

 428       return retval;

 429     }

 430 

 431     /// <summary>

 432     /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified 

 433     /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 

 434     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

 435     /// </summary>

 436     /// <remarks>

 437     /// This method provides no access to output parameters or the stored procedure's return value parameter.

 438     /// 

 439     /// e.g.:  

 440     ///  int result = ExecuteNonQuery(conn, trans, "PublishOrders", 24, 36);

 441     /// </remarks>

 442     /// <param name="transaction">A valid SqlTransaction</param>

 443     /// <param name="spName">The name of the stored procedure</param>

 444     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

 445     /// <returns>An int representing the number of rows affected by the command</returns>

 446     public static int ExecuteNonQuery(SqlTransaction transaction, string spName, params object[] parameterValues)

 447     {

 448       if (transaction == null) throw new ArgumentNullException("transaction");

 449       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

 450       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

 451 

 452       // If we receive parameter values, we need to figure out where they go

 453       if ((parameterValues != null) && (parameterValues.Length > 0))

 454       {

 455         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

 456         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);

 457 

 458         // Assign the provided values to these parameters based on parameter order

 459         AssignParameterValues(commandParameters, parameterValues);

 460 

 461         // Call the overload that takes an array of SqlParameters

 462         return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName, commandParameters);

 463       }

 464       else

 465       {

 466         // Otherwise we can just call the SP without params

 467         return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName);

 468       }

 469     }

 470 

 471     #endregion ExecuteNonQuery

 472 

 473     #region ExecuteDataset

 474 

 475     /// <summary>

 476     /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in 

 477     /// the connection string. 

 478     /// </summary>

 479     /// <remarks>

 480     /// e.g.:  

 481     ///  DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders");

 482     /// </remarks>

 483     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

 484     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 485     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 486     /// <returns>A dataset containing the resultset generated by the command</returns>

 487     public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText)

 488     {

 489       // Pass through the call providing null for the set of SqlParameters

 490       return ExecuteDataset(connectionString, commandType, commandText, (SqlParameter[])null);

 491     }

 492 

 493     /// <summary>

 494     /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string 

 495     /// using the provided parameters.

 496     /// </summary>

 497     /// <remarks>

 498     /// e.g.:  

 499     ///  DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));

 500     /// </remarks>

 501     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

 502     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 503     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 504     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

 505     /// <returns>A dataset containing the resultset generated by the command</returns>

 506     public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

 507     {

 508       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

 509 

 510       // Create & open a SqlConnection, and dispose of it after we are done

 511       using (SqlConnection connection = new SqlConnection(connectionString))

 512       {

 513         connection.Open();

 514 

 515         // Call the overload that takes a connection in place of the connection string

 516         return ExecuteDataset(connection, commandType, commandText, commandParameters);

 517       }

 518     }

 519 

 520     /// <summary>

 521     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 

 522     /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 

 523     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

 524     /// </summary>

 525     /// <remarks>

 526     /// This method provides no access to output parameters or the stored procedure's return value parameter.

 527     /// 

 528     /// e.g.:  

 529     ///  DataSet ds = ExecuteDataset(connString, "GetOrders", 24, 36);

 530     /// </remarks>

 531     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

 532     /// <param name="spName">The name of the stored procedure</param>

 533     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

 534     /// <returns>A dataset containing the resultset generated by the command</returns>

 535     public static DataSet ExecuteDataset(string connectionString, string spName, params object[] parameterValues)

 536     {

 537       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

 538       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

 539 

 540       // If we receive parameter values, we need to figure out where they go

 541       if ((parameterValues != null) && (parameterValues.Length > 0))

 542       {

 543         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

 544         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);

 545 

 546         // Assign the provided values to these parameters based on parameter order

 547         AssignParameterValues(commandParameters, parameterValues);

 548 

 549         // Call the overload that takes an array of SqlParameters

 550         return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName, commandParameters);

 551       }

 552       else

 553       {

 554         // Otherwise we can just call the SP without params

 555         return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName);

 556       }

 557     }

 558 

 559     /// <summary>

 560     /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. 

 561     /// </summary>

 562     /// <remarks>

 563     /// e.g.:  

 564     ///  DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders");

 565     /// </remarks>

 566     /// <param name="connection">A valid SqlConnection</param>

 567     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 568     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 569     /// <returns>A dataset containing the resultset generated by the command</returns>

 570     public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText)

 571     {

 572       // Pass through the call providing null for the set of SqlParameters

 573       return ExecuteDataset(connection, commandType, commandText, (SqlParameter[])null);

 574     }

 575 

 576     /// <summary>

 577     /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 

 578     /// using the provided parameters.

 579     /// </summary>

 580     /// <remarks>

 581     /// e.g.:  

 582     ///  DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));

 583     /// </remarks>

 584     /// <param name="connection">A valid SqlConnection</param>

 585     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 586     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 587     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

 588     /// <returns>A dataset containing the resultset generated by the command</returns>

 589     public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

 590     {

 591       if (connection == null) throw new ArgumentNullException("connection");

 592 

 593       // Create a command and prepare it for execution

 594       SqlCommand cmd = new SqlCommand();

 595       bool mustCloseConnection = false;

 596       PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);

 597 

 598       // Create the DataAdapter & DataSet

 599       using (SqlDataAdapter da = new SqlDataAdapter(cmd))

 600       {

 601         DataSet ds = new DataSet();

 602 

 603         // Fill the DataSet using default values for DataTable names, etc

 604         da.Fill(ds);

 605 

 606         // Detach the SqlParameters from the command object, so they can be used again

 607         cmd.Parameters.Clear();

 608 

 609         if (mustCloseConnection)

 610           connection.Close();

 611 

 612         // Return the dataset

 613         return ds;

 614       }

 615     }

 616 

 617     /// <summary>

 618     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 

 619     /// using the provided parameter values.  This method will query the database to discover the parameters for the 

 620     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

 621     /// </summary>

 622     /// <remarks>

 623     /// This method provides no access to output parameters or the stored procedure's return value parameter.

 624     /// 

 625     /// e.g.:  

 626     ///  DataSet ds = ExecuteDataset(conn, "GetOrders", 24, 36);

 627     /// </remarks>

 628     /// <param name="connection">A valid SqlConnection</param>

 629     /// <param name="spName">The name of the stored procedure</param>

 630     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

 631     /// <returns>A dataset containing the resultset generated by the command</returns>

 632     public static DataSet ExecuteDataset(SqlConnection connection, string spName, params object[] parameterValues)

 633     {

 634       if (connection == null) throw new ArgumentNullException("connection");

 635       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

 636 

 637       // If we receive parameter values, we need to figure out where they go

 638       if ((parameterValues != null) && (parameterValues.Length > 0))

 639       {

 640         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

 641         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);

 642 

 643         // Assign the provided values to these parameters based on parameter order

 644         AssignParameterValues(commandParameters, parameterValues);

 645 

 646         // Call the overload that takes an array of SqlParameters

 647         return ExecuteDataset(connection, CommandType.StoredProcedure, spName, commandParameters);

 648       }

 649       else

 650       {

 651         // Otherwise we can just call the SP without params

 652         return ExecuteDataset(connection, CommandType.StoredProcedure, spName);

 653       }

 654     }

 655 

 656     /// <summary>

 657     /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. 

 658     /// </summary>

 659     /// <remarks>

 660     /// e.g.:  

 661     ///  DataSet ds = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders");

 662     /// </remarks>

 663     /// <param name="transaction">A valid SqlTransaction</param>

 664     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 665     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 666     /// <returns>A dataset containing the resultset generated by the command</returns>

 667     public static DataSet ExecuteDataset(SqlTransaction transaction, CommandType commandType, string commandText)

 668     {

 669       // Pass through the call providing null for the set of SqlParameters

 670       return ExecuteDataset(transaction, commandType, commandText, (SqlParameter[])null);

 671     }

 672 

 673     /// <summary>

 674     /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction

 675     /// using the provided parameters.

 676     /// </summary>

 677     /// <remarks>

 678     /// e.g.:  

 679     ///  DataSet ds = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));

 680     /// </remarks>

 681     /// <param name="transaction">A valid SqlTransaction</param>

 682     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 683     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 684     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

 685     /// <returns>A dataset containing the resultset generated by the command</returns>

 686     public static DataSet ExecuteDataset(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

 687     {

 688       if (transaction == null) throw new ArgumentNullException("transaction");

 689       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

 690 

 691       // Create a command and prepare it for execution

 692       SqlCommand cmd = new SqlCommand();

 693       bool mustCloseConnection = false;

 694       PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);

 695 

 696       // Create the DataAdapter & DataSet

 697       using (SqlDataAdapter da = new SqlDataAdapter(cmd))

 698       {

 699         DataSet ds = new DataSet();

 700 

 701         // Fill the DataSet using default values for DataTable names, etc

 702         da.Fill(ds);

 703 

 704         // Detach the SqlParameters from the command object, so they can be used again

 705         cmd.Parameters.Clear();

 706 

 707         // Return the dataset

 708         return ds;

 709       }

 710     }

 711 

 712     /// <summary>

 713     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified 

 714     /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 

 715     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

 716     /// </summary>

 717     /// <remarks>

 718     /// This method provides no access to output parameters or the stored procedure's return value parameter.

 719     /// 

 720     /// e.g.:  

 721     ///  DataSet ds = ExecuteDataset(trans, "GetOrders", 24, 36);

 722     /// </remarks>

 723     /// <param name="transaction">A valid SqlTransaction</param>

 724     /// <param name="spName">The name of the stored procedure</param>

 725     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

 726     /// <returns>A dataset containing the resultset generated by the command</returns>

 727     public static DataSet ExecuteDataset(SqlTransaction transaction, string spName, params object[] parameterValues)

 728     {

 729       if (transaction == null) throw new ArgumentNullException("transaction");

 730       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

 731       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

 732 

 733       // If we receive parameter values, we need to figure out where they go

 734       if ((parameterValues != null) && (parameterValues.Length > 0))

 735       {

 736         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

 737         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);

 738 

 739         // Assign the provided values to these parameters based on parameter order

 740         AssignParameterValues(commandParameters, parameterValues);

 741 

 742         // Call the overload that takes an array of SqlParameters

 743         return ExecuteDataset(transaction, CommandType.StoredProcedure, spName, commandParameters);

 744       }

 745       else

 746       {

 747         // Otherwise we can just call the SP without params

 748         return ExecuteDataset(transaction, CommandType.StoredProcedure, spName);

 749       }

 750     }

 751 

 752     #endregion ExecuteDataset

 753 

 754     #region ExecuteReader

 755 

 756     /// <summary>

 757     /// This enum is used to indicate whether the connection was provided by the caller, or created by SqlHelper, so that

 758     /// we can set the appropriate CommandBehavior when calling ExecuteReader()

 759     /// </summary>

 760     private enum SqlConnectionOwnership

 761     {

 762       /// <summary>Connection is owned and managed by SqlHelper</summary>

 763       Internal,

 764       /// <summary>Connection is owned and managed by the caller</summary>

 765       External

 766     }

 767 

 768     /// <summary>

 769     /// Create and prepare a SqlCommand, and call ExecuteReader with the appropriate CommandBehavior.

 770     /// </summary>

 771     /// <remarks>

 772     /// If we created and opened the connection, we want the connection to be closed when the DataReader is closed.

 773     /// 

 774     /// If the caller provided the connection, we want to leave it to them to manage.

 775     /// </remarks>

 776     /// <param name="connection">A valid SqlConnection, on which to execute this command</param>

 777     /// <param name="transaction">A valid SqlTransaction, or 'null'</param>

 778     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 779     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 780     /// <param name="commandParameters">An array of SqlParameters to be associated with the command or 'null' if no parameters are required</param>

 781     /// <param name="connectionOwnership">Indicates whether the connection parameter was provided by the caller, or created by SqlHelper</param>

 782     /// <returns>SqlDataReader containing the results of the command</returns>

 783     private static SqlDataReader ExecuteReader(SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, SqlConnectionOwnership connectionOwnership)

 784     {

 785       if (connection == null) throw new ArgumentNullException("connection");

 786 

 787       bool mustCloseConnection = false;

 788       // Create a command and prepare it for execution

 789       SqlCommand cmd = new SqlCommand();

 790       try

 791       {

 792         PrepareCommand(cmd, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);

 793 

 794         // Create a reader

 795         SqlDataReader dataReader;

 796 

 797         // Call ExecuteReader with the appropriate CommandBehavior

 798         if (connectionOwnership == SqlConnectionOwnership.External)

 799         {

 800           dataReader = cmd.ExecuteReader();

 801         }

 802         else

 803         {

 804           dataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);

 805         }

 806 

 807         // Detach the SqlParameters from the command object, so they can be used again.

 808         // HACK: There is a problem here, the output parameter values are fletched 

 809         // when the reader is closed, so if the parameters are detached from the command

 810         // then the SqlReader can愒 set its values. 

 811         // When this happen, the parameters can愒 be used again in other command.

 812         bool canClear = true;

 813         foreach (SqlParameter commandParameter in cmd.Parameters)

 814         {

 815           if (commandParameter.Direction != ParameterDirection.Input)

 816             canClear = false;

 817         }

 818 

 819         if (canClear)

 820         {

 821           cmd.Parameters.Clear();

 822         }

 823 

 824         return dataReader;

 825       }

 826       catch

 827       {

 828         if (mustCloseConnection)

 829           connection.Close();

 830         throw;

 831       }

 832     }

 833 

 834     /// <summary>

 835     /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in 

 836     /// the connection string. 

 837     /// </summary>

 838     /// <remarks>

 839     /// e.g.:  

 840     ///  SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders");

 841     /// </remarks>

 842     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

 843     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 844     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 845     /// <returns>A SqlDataReader containing the resultset generated by the command</returns>

 846     public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText)

 847     {

 848       // Pass through the call providing null for the set of SqlParameters

 849       return ExecuteReader(connectionString, commandType, commandText, (SqlParameter[])null);

 850     }

 851 

 852     /// <summary>

 853     /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string 

 854     /// using the provided parameters.

 855     /// </summary>

 856     /// <remarks>

 857     /// e.g.:  

 858     ///  SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));

 859     /// </remarks>

 860     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

 861     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 862     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 863     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

 864     /// <returns>A SqlDataReader containing the resultset generated by the command</returns>

 865     public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

 866     {

 867       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

 868       SqlConnection connection = null;

 869       try

 870       {

 871         connection = new SqlConnection(connectionString);

 872         connection.Open();

 873 

 874         // Call the private overload that takes an internally owned connection in place of the connection string

 875         return ExecuteReader(connection, null, commandType, commandText, commandParameters, SqlConnectionOwnership.Internal);

 876       }

 877       catch

 878       {

 879         // If we fail to return the SqlDatReader, we need to close the connection ourselves

 880         if (connection != null) connection.Close();

 881         throw;

 882       }

 883 

 884     }

 885 

 886     /// <summary>

 887     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 

 888     /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 

 889     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

 890     /// </summary>

 891     /// <remarks>

 892     /// This method provides no access to output parameters or the stored procedure's return value parameter.

 893     /// 

 894     /// e.g.:  

 895     ///  SqlDataReader dr = ExecuteReader(connString, "GetOrders", 24, 36);

 896     /// </remarks>

 897     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

 898     /// <param name="spName">The name of the stored procedure</param>

 899     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

 900     /// <returns>A SqlDataReader containing the resultset generated by the command</returns>

 901     public static SqlDataReader ExecuteReader(string connectionString, string spName, params object[] parameterValues)

 902     {

 903       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

 904       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

 905 

 906       // If we receive parameter values, we need to figure out where they go

 907       if ((parameterValues != null) && (parameterValues.Length > 0))

 908       {

 909         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);

 910 

 911         AssignParameterValues(commandParameters, parameterValues);

 912 

 913         return ExecuteReader(connectionString, CommandType.StoredProcedure, spName, commandParameters);

 914       }

 915       else

 916       {

 917         // Otherwise we can just call the SP without params

 918         return ExecuteReader(connectionString, CommandType.StoredProcedure, spName);

 919       }

 920     }

 921 

 922     /// <summary>

 923     /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. 

 924     /// </summary>

 925     /// <remarks>

 926     /// e.g.:  

 927     ///  SqlDataReader dr = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders");

 928     /// </remarks>

 929     /// <param name="connection">A valid SqlConnection</param>

 930     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 931     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 932     /// <returns>A SqlDataReader containing the resultset generated by the command</returns>

 933     public static SqlDataReader ExecuteReader(SqlConnection connection, CommandType commandType, string commandText)

 934     {

 935       // Pass through the call providing null for the set of SqlParameters

 936       return ExecuteReader(connection, commandType, commandText, (SqlParameter[])null);

 937     }

 938 

 939     /// <summary>

 940     /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 

 941     /// using the provided parameters.

 942     /// </summary>

 943     /// <remarks>

 944     /// e.g.:  

 945     ///  SqlDataReader dr = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));

 946     /// </remarks>

 947     /// <param name="connection">A valid SqlConnection</param>

 948     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

 949     /// <param name="commandText">The stored procedure name or T-SQL command</param>

 950     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

 951     /// <returns>A SqlDataReader containing the resultset generated by the command</returns>

 952     public static SqlDataReader ExecuteReader(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

 953     {

 954       // Pass through the call to the private overload using a null transaction value and an externally owned connection

 955       return ExecuteReader(connection, (SqlTransaction)null, commandType, commandText, commandParameters, SqlConnectionOwnership.External);

 956     }

 957 

 958     /// <summary>

 959     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 

 960     /// using the provided parameter values.  This method will query the database to discover the parameters for the 

 961     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

 962     /// </summary>

 963     /// <remarks>

 964     /// This method provides no access to output parameters or the stored procedure's return value parameter.

 965     /// 

 966     /// e.g.:  

 967     ///  SqlDataReader dr = ExecuteReader(conn, "GetOrders", 24, 36);

 968     /// </remarks>

 969     /// <param name="connection">A valid SqlConnection</param>

 970     /// <param name="spName">The name of the stored procedure</param>

 971     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

 972     /// <returns>A SqlDataReader containing the resultset generated by the command</returns>

 973     public static SqlDataReader ExecuteReader(SqlConnection connection, string spName, params object[] parameterValues)

 974     {

 975       if (connection == null) throw new ArgumentNullException("connection");

 976       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

 977 

 978       // If we receive parameter values, we need to figure out where they go

 979       if ((parameterValues != null) && (parameterValues.Length > 0))

 980       {

 981         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);

 982 

 983         AssignParameterValues(commandParameters, parameterValues);

 984 

 985         return ExecuteReader(connection, CommandType.StoredProcedure, spName, commandParameters);

 986       }

 987       else

 988       {

 989         // Otherwise we can just call the SP without params

 990         return ExecuteReader(connection, CommandType.StoredProcedure, spName);

 991       }

 992     }

 993 

 994     /// <summary>

 995     /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. 

 996     /// </summary>

 997     /// <remarks>

 998     /// e.g.:  

 999     ///  SqlDataReader dr = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders");

1000     /// </remarks>

1001     /// <param name="transaction">A valid SqlTransaction</param>

1002     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1003     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1004     /// <returns>A SqlDataReader containing the resultset generated by the command</returns>

1005     public static SqlDataReader ExecuteReader(SqlTransaction transaction, CommandType commandType, string commandText)

1006     {

1007       // Pass through the call providing null for the set of SqlParameters

1008       return ExecuteReader(transaction, commandType, commandText, (SqlParameter[])null);

1009     }

1010 

1011     /// <summary>

1012     /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction

1013     /// using the provided parameters.

1014     /// </summary>

1015     /// <remarks>

1016     /// e.g.:  

1017     ///   SqlDataReader dr = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));

1018     /// </remarks>

1019     /// <param name="transaction">A valid SqlTransaction</param>

1020     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1021     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1022     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

1023     /// <returns>A SqlDataReader containing the resultset generated by the command</returns>

1024     public static SqlDataReader ExecuteReader(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

1025     {

1026       if (transaction == null) throw new ArgumentNullException("transaction");

1027       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

1028 

1029       // Pass through to private overload, indicating that the connection is owned by the caller

1030       return ExecuteReader(transaction.Connection, transaction, commandType, commandText, commandParameters, SqlConnectionOwnership.External);

1031     }

1032 

1033     /// <summary>

1034     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified

1035     /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 

1036     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

1037     /// </summary>

1038     /// <remarks>

1039     /// This method provides no access to output parameters or the stored procedure's return value parameter.

1040     /// 

1041     /// e.g.:  

1042     ///  SqlDataReader dr = ExecuteReader(trans, "GetOrders", 24, 36);

1043     /// </remarks>

1044     /// <param name="transaction">A valid SqlTransaction</param>

1045     /// <param name="spName">The name of the stored procedure</param>

1046     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

1047     /// <returns>A SqlDataReader containing the resultset generated by the command</returns>

1048     public static SqlDataReader ExecuteReader(SqlTransaction transaction, string spName, params object[] parameterValues)

1049     {

1050       if (transaction == null) throw new ArgumentNullException("transaction");

1051       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

1052       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

1053 

1054       // If we receive parameter values, we need to figure out where they go

1055       if ((parameterValues != null) && (parameterValues.Length > 0))

1056       {

1057         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);

1058 

1059         AssignParameterValues(commandParameters, parameterValues);

1060 

1061         return ExecuteReader(transaction, CommandType.StoredProcedure, spName, commandParameters);

1062       }

1063       else

1064       {

1065         // Otherwise we can just call the SP without params

1066         return ExecuteReader(transaction, CommandType.StoredProcedure, spName);

1067       }

1068     }

1069 

1070     #endregion ExecuteReader

1071 

1072     #region ExecuteScalar

1073 

1074     /// <summary>

1075     /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the database specified in 

1076     /// the connection string. 

1077     /// </summary>

1078     /// <remarks>

1079     /// e.g.:  

1080     ///  int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount");

1081     /// </remarks>

1082     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

1083     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1084     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1085     /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>

1086     public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText)

1087     {

1088       // Pass through the call providing null for the set of SqlParameters

1089       return ExecuteScalar(connectionString, commandType, commandText, (SqlParameter[])null);

1090     }

1091 

1092     /// <summary>

1093     /// Execute a SqlCommand (that returns a 1x1 resultset) against the database specified in the connection string 

1094     /// using the provided parameters.

1095     /// </summary>

1096     /// <remarks>

1097     /// e.g.:  

1098     ///  int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));

1099     /// </remarks>

1100     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

1101     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1102     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1103     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

1104     /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>

1105     public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

1106     {

1107       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

1108       // Create & open a SqlConnection, and dispose of it after we are done

1109       using (SqlConnection connection = new SqlConnection(connectionString))

1110       {

1111         connection.Open();

1112 

1113         // Call the overload that takes a connection in place of the connection string

1114         return ExecuteScalar(connection, commandType, commandText, commandParameters);

1115       }

1116     }

1117 

1118     /// <summary>

1119     /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the database specified in 

1120     /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 

1121     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

1122     /// </summary>

1123     /// <remarks>

1124     /// This method provides no access to output parameters or the stored procedure's return value parameter.

1125     /// 

1126     /// e.g.:  

1127     ///  int orderCount = (int)ExecuteScalar(connString, "GetOrderCount", 24, 36);

1128     /// </remarks>

1129     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

1130     /// <param name="spName">The name of the stored procedure</param>

1131     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

1132     /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>

1133     public static object ExecuteScalar(string connectionString, string spName, params object[] parameterValues)

1134     {

1135       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

1136       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

1137 

1138       // If we receive parameter values, we need to figure out where they go

1139       if ((parameterValues != null) && (parameterValues.Length > 0))

1140       {

1141         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

1142         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);

1143 

1144         // Assign the provided values to these parameters based on parameter order

1145         AssignParameterValues(commandParameters, parameterValues);

1146 

1147         // Call the overload that takes an array of SqlParameters

1148         return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName, commandParameters);

1149       }

1150       else

1151       {

1152         // Otherwise we can just call the SP without params

1153         return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName);

1154       }

1155     }

1156 

1157     /// <summary>

1158     /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the provided SqlConnection. 

1159     /// </summary>

1160     /// <remarks>

1161     /// e.g.:  

1162     ///  int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount");

1163     /// </remarks>

1164     /// <param name="connection">A valid SqlConnection</param>

1165     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1166     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1167     /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>

1168     public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText)

1169     {

1170       // Pass through the call providing null for the set of SqlParameters

1171       return ExecuteScalar(connection, commandType, commandText, (SqlParameter[])null);

1172     }

1173 

1174     /// <summary>

1175     /// Execute a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection 

1176     /// using the provided parameters.

1177     /// </summary>

1178     /// <remarks>

1179     /// e.g.:  

1180     ///  int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));

1181     /// </remarks>

1182     /// <param name="connection">A valid SqlConnection</param>

1183     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1184     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1185     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

1186     /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>

1187     public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

1188     {

1189       if (connection == null) throw new ArgumentNullException("connection");

1190 

1191       // Create a command and prepare it for execution

1192       SqlCommand cmd = new SqlCommand();

1193 

1194       bool mustCloseConnection = false;

1195       PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);

1196 

1197       // Execute the command & return the results

1198       object retval = cmd.ExecuteScalar();

1199 

1200       // Detach the SqlParameters from the command object, so they can be used again

1201       cmd.Parameters.Clear();

1202 

1203       if (mustCloseConnection)

1204         connection.Close();

1205 

1206       return retval;

1207     }

1208 

1209     /// <summary>

1210     /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection 

1211     /// using the provided parameter values.  This method will query the database to discover the parameters for the 

1212     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

1213     /// </summary>

1214     /// <remarks>

1215     /// This method provides no access to output parameters or the stored procedure's return value parameter.

1216     /// 

1217     /// e.g.:  

1218     ///  int orderCount = (int)ExecuteScalar(conn, "GetOrderCount", 24, 36);

1219     /// </remarks>

1220     /// <param name="connection">A valid SqlConnection</param>

1221     /// <param name="spName">The name of the stored procedure</param>

1222     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

1223     /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>

1224     public static object ExecuteScalar(SqlConnection connection, string spName, params object[] parameterValues)

1225     {

1226       if (connection == null) throw new ArgumentNullException("connection");

1227       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

1228 

1229       // If we receive parameter values, we need to figure out where they go

1230       if ((parameterValues != null) && (parameterValues.Length > 0))

1231       {

1232         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

1233         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);

1234 

1235         // Assign the provided values to these parameters based on parameter order

1236         AssignParameterValues(commandParameters, parameterValues);

1237 

1238         // Call the overload that takes an array of SqlParameters

1239         return ExecuteScalar(connection, CommandType.StoredProcedure, spName, commandParameters);

1240       }

1241       else

1242       {

1243         // Otherwise we can just call the SP without params

1244         return ExecuteScalar(connection, CommandType.StoredProcedure, spName);

1245       }

1246     }

1247 

1248     /// <summary>

1249     /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the provided SqlTransaction. 

1250     /// </summary>

1251     /// <remarks>

1252     /// e.g.:  

1253     ///  int orderCount = (int)ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount");

1254     /// </remarks>

1255     /// <param name="transaction">A valid SqlTransaction</param>

1256     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1257     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1258     /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>

1259     public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText)

1260     {

1261       // Pass through the call providing null for the set of SqlParameters

1262       return ExecuteScalar(transaction, commandType, commandText, (SqlParameter[])null);

1263     }

1264 

1265     /// <summary>

1266     /// Execute a SqlCommand (that returns a 1x1 resultset) against the specified SqlTransaction

1267     /// using the provided parameters.

1268     /// </summary>

1269     /// <remarks>

1270     /// e.g.:  

1271     ///  int orderCount = (int)ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));

1272     /// </remarks>

1273     /// <param name="transaction">A valid SqlTransaction</param>

1274     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1275     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1276     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

1277     /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>

1278     public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

1279     {

1280       if (transaction == null) throw new ArgumentNullException("transaction");

1281       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

1282 

1283       // Create a command and prepare it for execution

1284       SqlCommand cmd = new SqlCommand();

1285       bool mustCloseConnection = false;

1286       PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);

1287 

1288       // Execute the command & return the results

1289       object retval = cmd.ExecuteScalar();

1290 

1291       // Detach the SqlParameters from the command object, so they can be used again

1292       cmd.Parameters.Clear();

1293       return retval;

1294     }

1295 

1296     /// <summary>

1297     /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified

1298     /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 

1299     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

1300     /// </summary>

1301     /// <remarks>

1302     /// This method provides no access to output parameters or the stored procedure's return value parameter.

1303     /// 

1304     /// e.g.:  

1305     ///  int orderCount = (int)ExecuteScalar(trans, "GetOrderCount", 24, 36);

1306     /// </remarks>

1307     /// <param name="transaction">A valid SqlTransaction</param>

1308     /// <param name="spName">The name of the stored procedure</param>

1309     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

1310     /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>

1311     public static object ExecuteScalar(SqlTransaction transaction, string spName, params object[] parameterValues)

1312     {

1313       if (transaction == null) throw new ArgumentNullException("transaction");

1314       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

1315       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

1316 

1317       // If we receive parameter values, we need to figure out where they go

1318       if ((parameterValues != null) && (parameterValues.Length > 0))

1319       {

1320         // PPull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

1321         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);

1322 

1323         // Assign the provided values to these parameters based on parameter order

1324         AssignParameterValues(commandParameters, parameterValues);

1325 

1326         // Call the overload that takes an array of SqlParameters

1327         return ExecuteScalar(transaction, CommandType.StoredProcedure, spName, commandParameters);

1328       }

1329       else

1330       {

1331         // Otherwise we can just call the SP without params

1332         return ExecuteScalar(transaction, CommandType.StoredProcedure, spName);

1333       }

1334     }

1335 

1336     #endregion ExecuteScalar

1337 

1338     #region ExecuteXmlReader

1339     /// <summary>

1340     /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. 

1341     /// </summary>

1342     /// <remarks>

1343     /// e.g.:  

1344     ///  XmlReader r = ExecuteXmlReader(conn, CommandType.StoredProcedure, "GetOrders");

1345     /// </remarks>

1346     /// <param name="connection">A valid SqlConnection</param>

1347     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1348     /// <param name="commandText">The stored procedure name or T-SQL command using "FOR XML AUTO"</param>

1349     /// <returns>An XmlReader containing the resultset generated by the command</returns>

1350     public static XmlReader ExecuteXmlReader(SqlConnection connection, CommandType commandType, string commandText)

1351     {

1352       // Pass through the call providing null for the set of SqlParameters

1353       return ExecuteXmlReader(connection, commandType, commandText, (SqlParameter[])null);

1354     }

1355 

1356     /// <summary>

1357     /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 

1358     /// using the provided parameters.

1359     /// </summary>

1360     /// <remarks>

1361     /// e.g.:  

1362     ///  XmlReader r = ExecuteXmlReader(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));

1363     /// </remarks>

1364     /// <param name="connection">A valid SqlConnection</param>

1365     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1366     /// <param name="commandText">The stored procedure name or T-SQL command using "FOR XML AUTO"</param>

1367     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

1368     /// <returns>An XmlReader containing the resultset generated by the command</returns>

1369     public static XmlReader ExecuteXmlReader(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

1370     {

1371       if (connection == null) throw new ArgumentNullException("connection");

1372 

1373       bool mustCloseConnection = false;

1374       // Create a command and prepare it for execution

1375       SqlCommand cmd = new SqlCommand();

1376       try

1377       {

1378         PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);

1379 

1380         // Create the DataAdapter & DataSet

1381         XmlReader retval = cmd.ExecuteXmlReader();

1382 

1383         // Detach the SqlParameters from the command object, so they can be used again

1384         cmd.Parameters.Clear();

1385 

1386         return retval;

1387       }

1388       catch

1389       {

1390         if (mustCloseConnection)

1391           connection.Close();

1392         throw;

1393       }

1394     }

1395 

1396     /// <summary>

1397     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 

1398     /// using the provided parameter values.  This method will query the database to discover the parameters for the 

1399     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

1400     /// </summary>

1401     /// <remarks>

1402     /// This method provides no access to output parameters or the stored procedure's return value parameter.

1403     /// 

1404     /// e.g.:  

1405     ///  XmlReader r = ExecuteXmlReader(conn, "GetOrders", 24, 36);

1406     /// </remarks>

1407     /// <param name="connection">A valid SqlConnection</param>

1408     /// <param name="spName">The name of the stored procedure using "FOR XML AUTO"</param>

1409     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

1410     /// <returns>An XmlReader containing the resultset generated by the command</returns>

1411     public static XmlReader ExecuteXmlReader(SqlConnection connection, string spName, params object[] parameterValues)

1412     {

1413       if (connection == null) throw new ArgumentNullException("connection");

1414       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

1415 

1416       // If we receive parameter values, we need to figure out where they go

1417       if ((parameterValues != null) && (parameterValues.Length > 0))

1418       {

1419         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

1420         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);

1421 

1422         // Assign the provided values to these parameters based on parameter order

1423         AssignParameterValues(commandParameters, parameterValues);

1424 

1425         // Call the overload that takes an array of SqlParameters

1426         return ExecuteXmlReader(connection, CommandType.StoredProcedure, spName, commandParameters);

1427       }

1428       else

1429       {

1430         // Otherwise we can just call the SP without params

1431         return ExecuteXmlReader(connection, CommandType.StoredProcedure, spName);

1432       }

1433     }

1434 

1435     /// <summary>

1436     /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. 

1437     /// </summary>

1438     /// <remarks>

1439     /// e.g.:  

1440     ///  XmlReader r = ExecuteXmlReader(trans, CommandType.StoredProcedure, "GetOrders");

1441     /// </remarks>

1442     /// <param name="transaction">A valid SqlTransaction</param>

1443     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1444     /// <param name="commandText">The stored procedure name or T-SQL command using "FOR XML AUTO"</param>

1445     /// <returns>An XmlReader containing the resultset generated by the command</returns>

1446     public static XmlReader ExecuteXmlReader(SqlTransaction transaction, CommandType commandType, string commandText)

1447     {

1448       // Pass through the call providing null for the set of SqlParameters

1449       return ExecuteXmlReader(transaction, commandType, commandText, (SqlParameter[])null);

1450     }

1451 

1452     /// <summary>

1453     /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction

1454     /// using the provided parameters.

1455     /// </summary>

1456     /// <remarks>

1457     /// e.g.:  

1458     ///  XmlReader r = ExecuteXmlReader(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));

1459     /// </remarks>

1460     /// <param name="transaction">A valid SqlTransaction</param>

1461     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1462     /// <param name="commandText">The stored procedure name or T-SQL command using "FOR XML AUTO"</param>

1463     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

1464     /// <returns>An XmlReader containing the resultset generated by the command</returns>

1465     public static XmlReader ExecuteXmlReader(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)

1466     {

1467       if (transaction == null) throw new ArgumentNullException("transaction");

1468       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

1469 

1470       // Create a command and prepare it for execution

1471       SqlCommand cmd = new SqlCommand();

1472       bool mustCloseConnection = false;

1473       PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);

1474 

1475       // Create the DataAdapter & DataSet

1476       XmlReader retval = cmd.ExecuteXmlReader();

1477 

1478       // Detach the SqlParameters from the command object, so they can be used again

1479       cmd.Parameters.Clear();

1480       return retval;

1481     }

1482 

1483     /// <summary>

1484     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified 

1485     /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 

1486     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

1487     /// </summary>

1488     /// <remarks>

1489     /// This method provides no access to output parameters or the stored procedure's return value parameter.

1490     /// 

1491     /// e.g.:  

1492     ///  XmlReader r = ExecuteXmlReader(trans, "GetOrders", 24, 36);

1493     /// </remarks>

1494     /// <param name="transaction">A valid SqlTransaction</param>

1495     /// <param name="spName">The name of the stored procedure</param>

1496     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

1497     /// <returns>A dataset containing the resultset generated by the command</returns>

1498     public static XmlReader ExecuteXmlReader(SqlTransaction transaction, string spName, params object[] parameterValues)

1499     {

1500       if (transaction == null) throw new ArgumentNullException("transaction");

1501       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

1502       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

1503 

1504       // If we receive parameter values, we need to figure out where they go

1505       if ((parameterValues != null) && (parameterValues.Length > 0))

1506       {

1507         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

1508         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);

1509 

1510         // Assign the provided values to these parameters based on parameter order

1511         AssignParameterValues(commandParameters, parameterValues);

1512 

1513         // Call the overload that takes an array of SqlParameters

1514         return ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName, commandParameters);

1515       }

1516       else

1517       {

1518         // Otherwise we can just call the SP without params

1519         return ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName);

1520       }

1521     }

1522 

1523     #endregion ExecuteXmlReader

1524 

1525     #region FillDataset

1526     /// <summary>

1527     /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in 

1528     /// the connection string. 

1529     /// </summary>

1530     /// <remarks>

1531     /// e.g.:  

1532     ///  FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"});

1533     /// </remarks>

1534     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

1535     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1536     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1537     /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>

1538     /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced

1539     /// by a user defined name (probably the actual table name)</param>

1540     public static void FillDataset(string connectionString, CommandType commandType, string commandText, DataSet dataSet, string[] tableNames)

1541     {

1542       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

1543       if (dataSet == null) throw new ArgumentNullException("dataSet");

1544 

1545       // Create & open a SqlConnection, and dispose of it after we are done

1546       using (SqlConnection connection = new SqlConnection(connectionString))

1547       {

1548         connection.Open();

1549 

1550         // Call the overload that takes a connection in place of the connection string

1551         FillDataset(connection, commandType, commandText, dataSet, tableNames);

1552       }

1553     }

1554 

1555     /// <summary>

1556     /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string 

1557     /// using the provided parameters.

1558     /// </summary>

1559     /// <remarks>

1560     /// e.g.:  

1561     ///  FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24));

1562     /// </remarks>

1563     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

1564     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1565     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1566     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

1567     /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>

1568     /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced

1569     /// by a user defined name (probably the actual table name)

1570     /// </param>

1571     public static void FillDataset(string connectionString, CommandType commandType,

1572         string commandText, DataSet dataSet, string[] tableNames,

1573         params SqlParameter[] commandParameters)

1574     {

1575       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

1576       if (dataSet == null) throw new ArgumentNullException("dataSet");

1577       // Create & open a SqlConnection, and dispose of it after we are done

1578       using (SqlConnection connection = new SqlConnection(connectionString))

1579       {

1580         connection.Open();

1581 

1582         // Call the overload that takes a connection in place of the connection string

1583         FillDataset(connection, commandType, commandText, dataSet, tableNames, commandParameters);

1584       }

1585     }

1586 

1587     /// <summary>

1588     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 

1589     /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 

1590     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

1591     /// </summary>

1592     /// <remarks>

1593     /// This method provides no access to output parameters or the stored procedure's return value parameter.

1594     /// 

1595     /// e.g.:  

1596     ///  FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, 24);

1597     /// </remarks>

1598     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

1599     /// <param name="spName">The name of the stored procedure</param>

1600     /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>

1601     /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced

1602     /// by a user defined name (probably the actual table name)

1603     /// </param>    

1604     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

1605     public static void FillDataset(string connectionString, string spName,

1606         DataSet dataSet, string[] tableNames,

1607         params object[] parameterValues)

1608     {

1609       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

1610       if (dataSet == null) throw new ArgumentNullException("dataSet");

1611       // Create & open a SqlConnection, and dispose of it after we are done

1612       using (SqlConnection connection = new SqlConnection(connectionString))

1613       {

1614         connection.Open();

1615 

1616         // Call the overload that takes a connection in place of the connection string

1617         FillDataset(connection, spName, dataSet, tableNames, parameterValues);

1618       }

1619     }

1620 

1621     /// <summary>

1622     /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. 

1623     /// </summary>

1624     /// <remarks>

1625     /// e.g.:  

1626     ///  FillDataset(conn, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"});

1627     /// </remarks>

1628     /// <param name="connection">A valid SqlConnection</param>

1629     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1630     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1631     /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>

1632     /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced

1633     /// by a user defined name (probably the actual table name)

1634     /// </param>    

1635     public static void FillDataset(SqlConnection connection, CommandType commandType,

1636         string commandText, DataSet dataSet, string[] tableNames)

1637     {

1638       FillDataset(connection, commandType, commandText, dataSet, tableNames, null);

1639     }

1640 

1641     /// <summary>

1642     /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 

1643     /// using the provided parameters.

1644     /// </summary>

1645     /// <remarks>

1646     /// e.g.:  

1647     ///  FillDataset(conn, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24));

1648     /// </remarks>

1649     /// <param name="connection">A valid SqlConnection</param>

1650     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1651     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1652     /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>

1653     /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced

1654     /// by a user defined name (probably the actual table name)

1655     /// </param>

1656     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

1657     public static void FillDataset(SqlConnection connection, CommandType commandType,

1658         string commandText, DataSet dataSet, string[] tableNames,

1659         params SqlParameter[] commandParameters)

1660     {

1661       FillDataset(connection, null, commandType, commandText, dataSet, tableNames, commandParameters);

1662     }

1663 

1664     /// <summary>

1665     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 

1666     /// using the provided parameter values.  This method will query the database to discover the parameters for the 

1667     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

1668     /// </summary>

1669     /// <remarks>

1670     /// This method provides no access to output parameters or the stored procedure's return value parameter.

1671     /// 

1672     /// e.g.:  

1673     ///  FillDataset(conn, "GetOrders", ds, new string[] {"orders"}, 24, 36);

1674     /// </remarks>

1675     /// <param name="connection">A valid SqlConnection</param>

1676     /// <param name="spName">The name of the stored procedure</param>

1677     /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>

1678     /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced

1679     /// by a user defined name (probably the actual table name)

1680     /// </param>

1681     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

1682     public static void FillDataset(SqlConnection connection, string spName,

1683         DataSet dataSet, string[] tableNames,

1684         params object[] parameterValues)

1685     {

1686       if (connection == null) throw new ArgumentNullException("connection");

1687       if (dataSet == null) throw new ArgumentNullException("dataSet");

1688       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

1689 

1690       // If we receive parameter values, we need to figure out where they go

1691       if ((parameterValues != null) && (parameterValues.Length > 0))

1692       {

1693         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

1694         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);

1695 

1696         // Assign the provided values to these parameters based on parameter order

1697         AssignParameterValues(commandParameters, parameterValues);

1698 

1699         // Call the overload that takes an array of SqlParameters

1700         FillDataset(connection, CommandType.StoredProcedure, spName, dataSet, tableNames, commandParameters);

1701       }

1702       else

1703       {

1704         // Otherwise we can just call the SP without params

1705         FillDataset(connection, CommandType.StoredProcedure, spName, dataSet, tableNames);

1706       }

1707     }

1708 

1709     /// <summary>

1710     /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. 

1711     /// </summary>

1712     /// <remarks>

1713     /// e.g.:  

1714     ///  FillDataset(trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"});

1715     /// </remarks>

1716     /// <param name="transaction">A valid SqlTransaction</param>

1717     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1718     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1719     /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>

1720     /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced

1721     /// by a user defined name (probably the actual table name)

1722     /// </param>

1723     public static void FillDataset(SqlTransaction transaction, CommandType commandType,

1724         string commandText,

1725         DataSet dataSet, string[] tableNames)

1726     {

1727       FillDataset(transaction, commandType, commandText, dataSet, tableNames, null);

1728     }

1729 

1730     /// <summary>

1731     /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction

1732     /// using the provided parameters.

1733     /// </summary>

1734     /// <remarks>

1735     /// e.g.:  

1736     ///  FillDataset(trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24));

1737     /// </remarks>

1738     /// <param name="transaction">A valid SqlTransaction</param>

1739     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1740     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1741     /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>

1742     /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced

1743     /// by a user defined name (probably the actual table name)

1744     /// </param>

1745     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

1746     public static void FillDataset(SqlTransaction transaction, CommandType commandType,

1747         string commandText, DataSet dataSet, string[] tableNames,

1748         params SqlParameter[] commandParameters)

1749     {

1750       FillDataset(transaction.Connection, transaction, commandType, commandText, dataSet, tableNames, commandParameters);

1751     }

1752 

1753     /// <summary>

1754     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified 

1755     /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 

1756     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

1757     /// </summary>

1758     /// <remarks>

1759     /// This method provides no access to output parameters or the stored procedure's return value parameter.

1760     /// 

1761     /// e.g.:  

1762     ///  FillDataset(trans, "GetOrders", ds, new string[]{"orders"}, 24, 36);

1763     /// </remarks>

1764     /// <param name="transaction">A valid SqlTransaction</param>

1765     /// <param name="spName">The name of the stored procedure</param>

1766     /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>

1767     /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced

1768     /// by a user defined name (probably the actual table name)

1769     /// </param>

1770     /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>

1771     public static void FillDataset(SqlTransaction transaction, string spName,

1772         DataSet dataSet, string[] tableNames,

1773         params object[] parameterValues)

1774     {

1775       if (transaction == null) throw new ArgumentNullException("transaction");

1776       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

1777       if (dataSet == null) throw new ArgumentNullException("dataSet");

1778       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

1779 

1780       // If we receive parameter values, we need to figure out where they go

1781       if ((parameterValues != null) && (parameterValues.Length > 0))

1782       {

1783         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

1784         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);

1785 

1786         // Assign the provided values to these parameters based on parameter order

1787         AssignParameterValues(commandParameters, parameterValues);

1788 

1789         // Call the overload that takes an array of SqlParameters

1790         FillDataset(transaction, CommandType.StoredProcedure, spName, dataSet, tableNames, commandParameters);

1791       }

1792       else

1793       {

1794         // Otherwise we can just call the SP without params

1795         FillDataset(transaction, CommandType.StoredProcedure, spName, dataSet, tableNames);

1796       }

1797     }

1798 

1799     /// <summary>

1800     /// Private helper method that execute a SqlCommand (that returns a resultset) against the specified SqlTransaction and SqlConnection

1801     /// using the provided parameters.

1802     /// </summary>

1803     /// <remarks>

1804     /// e.g.:  

1805     ///  FillDataset(conn, trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24));

1806     /// </remarks>

1807     /// <param name="connection">A valid SqlConnection</param>

1808     /// <param name="transaction">A valid SqlTransaction</param>

1809     /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>

1810     /// <param name="commandText">The stored procedure name or T-SQL command</param>

1811     /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>

1812     /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced

1813     /// by a user defined name (probably the actual table name)

1814     /// </param>

1815     /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>

1816     private static void FillDataset(SqlConnection connection, SqlTransaction transaction, CommandType commandType,

1817       string commandText, DataSet dataSet, string[] tableNames,

1818       params SqlParameter[] commandParameters)

1819     {

1820       if (connection == null) throw new ArgumentNullException("connection");

1821       if (dataSet == null) throw new ArgumentNullException("dataSet");

1822 

1823       // Create a command and prepare it for execution

1824       SqlCommand command = new SqlCommand();

1825       bool mustCloseConnection = false;

1826       PrepareCommand(command, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);

1827 

1828       // Create the DataAdapter & DataSet

1829       using (SqlDataAdapter dataAdapter = new SqlDataAdapter(command))

1830       {

1831 

1832         // Add the table mappings specified by the user

1833         if (tableNames != null && tableNames.Length > 0)

1834         {

1835           string tableName = "Table";

1836           for (int index = 0; index < tableNames.Length; index++)

1837           {

1838             if (tableNames[index] == null || tableNames[index].Length == 0) throw new ArgumentException("The tableNames parameter must contain a list of tables, a value was provided as null or empty string.", "tableNames");

1839             dataAdapter.TableMappings.Add(tableName, tableNames[index]);

1840             tableName += (index + 1).ToString();

1841           }

1842         }

1843 

1844         // Fill the DataSet using default values for DataTable names, etc

1845         dataAdapter.Fill(dataSet);

1846 

1847         // Detach the SqlParameters from the command object, so they can be used again

1848         command.Parameters.Clear();

1849       }

1850 

1851       if (mustCloseConnection)

1852         connection.Close();

1853     }

1854     #endregion

1855 

1856     #region UpdateDataset

1857     /// <summary>

1858     /// Executes the respective command for each inserted, updated, or deleted row in the DataSet.

1859     /// </summary>

1860     /// <remarks>

1861     /// e.g.:  

1862     ///  UpdateDataset(conn, insertCommand, deleteCommand, updateCommand, dataSet, "Order");

1863     /// </remarks>

1864     /// <param name="insertCommand">A valid transact-SQL statement or stored procedure to insert new records into the data source</param>

1865     /// <param name="deleteCommand">A valid transact-SQL statement or stored procedure to delete records from the data source</param>

1866     /// <param name="updateCommand">A valid transact-SQL statement or stored procedure used to update records in the data source</param>

1867     /// <param name="dataSet">The DataSet used to update the data source</param>

1868     /// <param name="tableName">The DataTable used to update the data source.</param>

1869     public static void UpdateDataset(SqlCommand insertCommand, SqlCommand deleteCommand, SqlCommand updateCommand, DataSet dataSet, string tableName)

1870     {

1871       if (insertCommand == null) throw new ArgumentNullException("insertCommand");

1872       if (deleteCommand == null) throw new ArgumentNullException("deleteCommand");

1873       if (updateCommand == null) throw new ArgumentNullException("updateCommand");

1874       if (tableName == null || tableName.Length == 0) throw new ArgumentNullException("tableName");

1875 

1876       // Create a SqlDataAdapter, and dispose of it after we are done

1877       using (SqlDataAdapter dataAdapter = new SqlDataAdapter())

1878       {

1879         // Set the data adapter commands

1880         dataAdapter.UpdateCommand = updateCommand;

1881         dataAdapter.InsertCommand = insertCommand;

1882         dataAdapter.DeleteCommand = deleteCommand;

1883 

1884         // Update the dataset changes in the data source

1885         dataAdapter.Update(dataSet, tableName);

1886 

1887         // Commit all the changes made to the DataSet

1888         dataSet.AcceptChanges();

1889       }

1890     }

1891     #endregion

1892 

1893     #region CreateCommand

1894     /// <summary>

1895     /// Simplify the creation of a Sql command object by allowing

1896     /// a stored procedure and optional parameters to be provided

1897     /// </summary>

1898     /// <remarks>

1899     /// e.g.:  

1900     ///  SqlCommand command = CreateCommand(conn, "AddCustomer", "CustomerID", "CustomerName");

1901     /// </remarks>

1902     /// <param name="connection">A valid SqlConnection object</param>

1903     /// <param name="spName">The name of the stored procedure</param>

1904     /// <param name="sourceColumns">An array of string to be assigned as the source columns of the stored procedure parameters</param>

1905     /// <returns>A valid SqlCommand object</returns>

1906     public static SqlCommand CreateCommand(SqlConnection connection, string spName, params string[] sourceColumns)

1907     {

1908       if (connection == null) throw new ArgumentNullException("connection");

1909       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

1910 

1911       // Create a SqlCommand

1912       SqlCommand cmd = new SqlCommand(spName, connection);

1913       cmd.CommandType = CommandType.StoredProcedure;

1914 

1915       // If we receive parameter values, we need to figure out where they go

1916       if ((sourceColumns != null) && (sourceColumns.Length > 0))

1917       {

1918         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

1919         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);

1920 

1921         // Assign the provided source columns to these parameters based on parameter order

1922         for (int index = 0; index < sourceColumns.Length; index++)

1923           commandParameters[index].SourceColumn = sourceColumns[index];

1924 

1925         // Attach the discovered parameters to the SqlCommand object

1926         AttachParameters(cmd, commandParameters);

1927       }

1928 

1929       return cmd;

1930     }

1931     #endregion

1932 

1933     #region ExecuteNonQueryTypedParams

1934     /// <summary>

1935     /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the database specified in 

1936     /// the connection string using the dataRow column values as the stored procedure's parameters values.

1937     /// This method will query the database to discover the parameters for the 

1938     /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.

1939     /// </summary>

1940     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

1941     /// <param name="spName">The name of the stored procedure</param>

1942     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>

1943     /// <returns>An int representing the number of rows affected by the command</returns>

1944     public static int ExecuteNonQueryTypedParams(String connectionString, String spName, DataRow dataRow)

1945     {

1946       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

1947       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

1948 

1949       // If the row has values, the store procedure parameters must be initialized

1950       if (dataRow != null && dataRow.ItemArray.Length > 0)

1951       {

1952         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

1953         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);

1954 

1955         // Set the parameters values

1956         AssignParameterValues(commandParameters, dataRow);

1957 

1958         return SqlHelper.ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters);

1959       }

1960       else

1961       {

1962         return SqlHelper.ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName);

1963       }

1964     }

1965 

1966     /// <summary>

1967     /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified SqlConnection 

1968     /// using the dataRow column values as the stored procedure's parameters values.  

1969     /// This method will query the database to discover the parameters for the 

1970     /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.

1971     /// </summary>

1972     /// <param name="connection">A valid SqlConnection object</param>

1973     /// <param name="spName">The name of the stored procedure</param>

1974     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>

1975     /// <returns>An int representing the number of rows affected by the command</returns>

1976     public static int ExecuteNonQueryTypedParams(SqlConnection connection, String spName, DataRow dataRow)

1977     {

1978       if (connection == null) throw new ArgumentNullException("connection");

1979       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

1980 

1981       // If the row has values, the store procedure parameters must be initialized

1982       if (dataRow != null && dataRow.ItemArray.Length > 0)

1983       {

1984         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

1985         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);

1986 

1987         // Set the parameters values

1988         AssignParameterValues(commandParameters, dataRow);

1989 

1990         return SqlHelper.ExecuteNonQuery(connection, CommandType.StoredProcedure, spName, commandParameters);

1991       }

1992       else

1993       {

1994         return SqlHelper.ExecuteNonQuery(connection, CommandType.StoredProcedure, spName);

1995       }

1996     }

1997 

1998     /// <summary>

1999     /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified

2000     /// SqlTransaction using the dataRow column values as the stored procedure's parameters values.

2001     /// This method will query the database to discover the parameters for the 

2002     /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.

2003     /// </summary>

2004     /// <param name="transaction">A valid SqlTransaction object</param>

2005     /// <param name="spName">The name of the stored procedure</param>

2006     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>

2007     /// <returns>An int representing the number of rows affected by the command</returns>

2008     public static int ExecuteNonQueryTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)

2009     {

2010       if (transaction == null) throw new ArgumentNullException("transaction");

2011       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

2012       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2013 

2014       // Sf the row has values, the store procedure parameters must be initialized

2015       if (dataRow != null && dataRow.ItemArray.Length > 0)

2016       {

2017         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

2018         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);

2019 

2020         // Set the parameters values

2021         AssignParameterValues(commandParameters, dataRow);

2022 

2023         return SqlHelper.ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName, commandParameters);

2024       }

2025       else

2026       {

2027         return SqlHelper.ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName);

2028       }

2029     }

2030     #endregion

2031 

2032     #region ExecuteDatasetTypedParams

2033     /// <summary>

2034     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 

2035     /// the connection string using the dataRow column values as the stored procedure's parameters values.

2036     /// This method will query the database to discover the parameters for the 

2037     /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.

2038     /// </summary>

2039     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

2040     /// <param name="spName">The name of the stored procedure</param>

2041     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>

2042     /// <returns>A dataset containing the resultset generated by the command</returns>

2043     public static DataSet ExecuteDatasetTypedParams(string connectionString, String spName, DataRow dataRow)

2044     {

2045       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

2046       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2047 

2048       //If the row has values, the store procedure parameters must be initialized

2049       if (dataRow != null && dataRow.ItemArray.Length > 0)

2050       {

2051         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

2052         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);

2053 

2054         // Set the parameters values

2055         AssignParameterValues(commandParameters, dataRow);

2056 

2057         return SqlHelper.ExecuteDataset(connectionString, CommandType.StoredProcedure, spName, commandParameters);

2058       }

2059       else

2060       {

2061         return SqlHelper.ExecuteDataset(connectionString, CommandType.StoredProcedure, spName);

2062       }

2063     }

2064 

2065     /// <summary>

2066     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 

2067     /// using the dataRow column values as the store procedure's parameters values.

2068     /// This method will query the database to discover the parameters for the 

2069     /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.

2070     /// </summary>

2071     /// <param name="connection">A valid SqlConnection object</param>

2072     /// <param name="spName">The name of the stored procedure</param>

2073     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>

2074     /// <returns>A dataset containing the resultset generated by the command</returns>

2075     public static DataSet ExecuteDatasetTypedParams(SqlConnection connection, String spName, DataRow dataRow)

2076     {

2077       if (connection == null) throw new ArgumentNullException("connection");

2078       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2079 

2080       // If the row has values, the store procedure parameters must be initialized

2081       if (dataRow != null && dataRow.ItemArray.Length > 0)

2082       {

2083         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

2084         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);

2085 

2086         // Set the parameters values

2087         AssignParameterValues(commandParameters, dataRow);

2088 

2089         return SqlHelper.ExecuteDataset(connection, CommandType.StoredProcedure, spName, commandParameters);

2090       }

2091       else

2092       {

2093         return SqlHelper.ExecuteDataset(connection, CommandType.StoredProcedure, spName);

2094       }

2095     }

2096 

2097     /// <summary>

2098     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlTransaction 

2099     /// using the dataRow column values as the stored procedure's parameters values.

2100     /// This method will query the database to discover the parameters for the 

2101     /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.

2102     /// </summary>

2103     /// <param name="transaction">A valid SqlTransaction object</param>

2104     /// <param name="spName">The name of the stored procedure</param>

2105     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>

2106     /// <returns>A dataset containing the resultset generated by the command</returns>

2107     public static DataSet ExecuteDatasetTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)

2108     {

2109       if (transaction == null) throw new ArgumentNullException("transaction");

2110       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

2111       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2112 

2113       // If the row has values, the store procedure parameters must be initialized

2114       if (dataRow != null && dataRow.ItemArray.Length > 0)

2115       {

2116         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

2117         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);

2118 

2119         // Set the parameters values

2120         AssignParameterValues(commandParameters, dataRow);

2121 

2122         return SqlHelper.ExecuteDataset(transaction, CommandType.StoredProcedure, spName, commandParameters);

2123       }

2124       else

2125       {

2126         return SqlHelper.ExecuteDataset(transaction, CommandType.StoredProcedure, spName);

2127       }

2128     }

2129 

2130     #endregion

2131 

2132     #region ExecuteReaderTypedParams

2133     /// <summary>

2134     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 

2135     /// the connection string using the dataRow column values as the stored procedure's parameters values.

2136     /// This method will query the database to discover the parameters for the 

2137     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

2138     /// </summary>

2139     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

2140     /// <param name="spName">The name of the stored procedure</param>

2141     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>

2142     /// <returns>A SqlDataReader containing the resultset generated by the command</returns>

2143     public static SqlDataReader ExecuteReaderTypedParams(String connectionString, String spName, DataRow dataRow)

2144     {

2145       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

2146       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2147 

2148       // If the row has values, the store procedure parameters must be initialized

2149       if (dataRow != null && dataRow.ItemArray.Length > 0)

2150       {

2151         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

2152         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);

2153 

2154         // Set the parameters values

2155         AssignParameterValues(commandParameters, dataRow);

2156 

2157         return SqlHelper.ExecuteReader(connectionString, CommandType.StoredProcedure, spName, commandParameters);

2158       }

2159       else

2160       {

2161         return SqlHelper.ExecuteReader(connectionString, CommandType.StoredProcedure, spName);

2162       }

2163     }

2164 

2165 

2166     /// <summary>

2167     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 

2168     /// using the dataRow column values as the stored procedure's parameters values.

2169     /// This method will query the database to discover the parameters for the 

2170     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

2171     /// </summary>

2172     /// <param name="connection">A valid SqlConnection object</param>

2173     /// <param name="spName">The name of the stored procedure</param>

2174     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>

2175     /// <returns>A SqlDataReader containing the resultset generated by the command</returns>

2176     public static SqlDataReader ExecuteReaderTypedParams(SqlConnection connection, String spName, DataRow dataRow)

2177     {

2178       if (connection == null) throw new ArgumentNullException("connection");

2179       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2180 

2181       // If the row has values, the store procedure parameters must be initialized

2182       if (dataRow != null && dataRow.ItemArray.Length > 0)

2183       {

2184         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

2185         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);

2186 

2187         // Set the parameters values

2188         AssignParameterValues(commandParameters, dataRow);

2189 

2190         return SqlHelper.ExecuteReader(connection, CommandType.StoredProcedure, spName, commandParameters);

2191       }

2192       else

2193       {

2194         return SqlHelper.ExecuteReader(connection, CommandType.StoredProcedure, spName);

2195       }

2196     }

2197 

2198     /// <summary>

2199     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlTransaction 

2200     /// using the dataRow column values as the stored procedure's parameters values.

2201     /// This method will query the database to discover the parameters for the 

2202     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

2203     /// </summary>

2204     /// <param name="transaction">A valid SqlTransaction object</param>

2205     /// <param name="spName">The name of the stored procedure</param>

2206     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>

2207     /// <returns>A SqlDataReader containing the resultset generated by the command</returns>

2208     public static SqlDataReader ExecuteReaderTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)

2209     {

2210       if (transaction == null) throw new ArgumentNullException("transaction");

2211       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

2212       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2213 

2214       // If the row has values, the store procedure parameters must be initialized

2215       if (dataRow != null && dataRow.ItemArray.Length > 0)

2216       {

2217         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

2218         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);

2219 

2220         // Set the parameters values

2221         AssignParameterValues(commandParameters, dataRow);

2222 

2223         return SqlHelper.ExecuteReader(transaction, CommandType.StoredProcedure, spName, commandParameters);

2224       }

2225       else

2226       {

2227         return SqlHelper.ExecuteReader(transaction, CommandType.StoredProcedure, spName);

2228       }

2229     }

2230     #endregion

2231 

2232     #region ExecuteScalarTypedParams

2233     /// <summary>

2234     /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the database specified in 

2235     /// the connection string using the dataRow column values as the stored procedure's parameters values.

2236     /// This method will query the database to discover the parameters for the 

2237     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

2238     /// </summary>

2239     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

2240     /// <param name="spName">The name of the stored procedure</param>

2241     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>

2242     /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>

2243     public static object ExecuteScalarTypedParams(String connectionString, String spName, DataRow dataRow)

2244     {

2245       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

2246       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2247 

2248       // If the row has values, the store procedure parameters must be initialized

2249       if (dataRow != null && dataRow.ItemArray.Length > 0)

2250       {

2251         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

2252         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);

2253 

2254         // Set the parameters values

2255         AssignParameterValues(commandParameters, dataRow);

2256 

2257         return SqlHelper.ExecuteScalar(connectionString, CommandType.StoredProcedure, spName, commandParameters);

2258       }

2259       else

2260       {

2261         return SqlHelper.ExecuteScalar(connectionString, CommandType.StoredProcedure, spName);

2262       }

2263     }

2264 

2265     /// <summary>

2266     /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection 

2267     /// using the dataRow column values as the stored procedure's parameters values.

2268     /// This method will query the database to discover the parameters for the 

2269     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

2270     /// </summary>

2271     /// <param name="connection">A valid SqlConnection object</param>

2272     /// <param name="spName">The name of the stored procedure</param>

2273     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>

2274     /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>

2275     public static object ExecuteScalarTypedParams(SqlConnection connection, String spName, DataRow dataRow)

2276     {

2277       if (connection == null) throw new ArgumentNullException("connection");

2278       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2279 

2280       // If the row has values, the store procedure parameters must be initialized

2281       if (dataRow != null && dataRow.ItemArray.Length > 0)

2282       {

2283         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

2284         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);

2285 

2286         // Set the parameters values

2287         AssignParameterValues(commandParameters, dataRow);

2288 

2289         return SqlHelper.ExecuteScalar(connection, CommandType.StoredProcedure, spName, commandParameters);

2290       }

2291       else

2292       {

2293         return SqlHelper.ExecuteScalar(connection, CommandType.StoredProcedure, spName);

2294       }

2295     }

2296 

2297     /// <summary>

2298     /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified SqlTransaction

2299     /// using the dataRow column values as the stored procedure's parameters values.

2300     /// This method will query the database to discover the parameters for the 

2301     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

2302     /// </summary>

2303     /// <param name="transaction">A valid SqlTransaction object</param>

2304     /// <param name="spName">The name of the stored procedure</param>

2305     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>

2306     /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>

2307     public static object ExecuteScalarTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)

2308     {

2309       if (transaction == null) throw new ArgumentNullException("transaction");

2310       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

2311       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2312 

2313       // If the row has values, the store procedure parameters must be initialized

2314       if (dataRow != null && dataRow.ItemArray.Length > 0)

2315       {

2316         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

2317         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);

2318 

2319         // Set the parameters values

2320         AssignParameterValues(commandParameters, dataRow);

2321 

2322         return SqlHelper.ExecuteScalar(transaction, CommandType.StoredProcedure, spName, commandParameters);

2323       }

2324       else

2325       {

2326         return SqlHelper.ExecuteScalar(transaction, CommandType.StoredProcedure, spName);

2327       }

2328     }

2329     #endregion

2330 

2331     #region ExecuteXmlReaderTypedParams

2332     /// <summary>

2333     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 

2334     /// using the dataRow column values as the stored procedure's parameters values.

2335     /// This method will query the database to discover the parameters for the 

2336     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

2337     /// </summary>

2338     /// <param name="connection">A valid SqlConnection object</param>

2339     /// <param name="spName">The name of the stored procedure</param>

2340     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>

2341     /// <returns>An XmlReader containing the resultset generated by the command</returns>

2342     public static XmlReader ExecuteXmlReaderTypedParams(SqlConnection connection, String spName, DataRow dataRow)

2343     {

2344       if (connection == null) throw new ArgumentNullException("connection");

2345       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2346 

2347       // If the row has values, the store procedure parameters must be initialized

2348       if (dataRow != null && dataRow.ItemArray.Length > 0)

2349       {

2350         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

2351         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);

2352 

2353         // Set the parameters values

2354         AssignParameterValues(commandParameters, dataRow);

2355 

2356         return SqlHelper.ExecuteXmlReader(connection, CommandType.StoredProcedure, spName, commandParameters);

2357       }

2358       else

2359       {

2360         return SqlHelper.ExecuteXmlReader(connection, CommandType.StoredProcedure, spName);

2361       }

2362     }

2363 

2364     /// <summary>

2365     /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlTransaction 

2366     /// using the dataRow column values as the stored procedure's parameters values.

2367     /// This method will query the database to discover the parameters for the 

2368     /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.

2369     /// </summary>

2370     /// <param name="transaction">A valid SqlTransaction object</param>

2371     /// <param name="spName">The name of the stored procedure</param>

2372     /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>

2373     /// <returns>An XmlReader containing the resultset generated by the command</returns>

2374     public static XmlReader ExecuteXmlReaderTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)

2375     {

2376       if (transaction == null) throw new ArgumentNullException("transaction");

2377       if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

2378       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2379 

2380       // If the row has values, the store procedure parameters must be initialized

2381       if (dataRow != null && dataRow.ItemArray.Length > 0)

2382       {

2383         // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)

2384         SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);

2385 

2386         // Set the parameters values

2387         AssignParameterValues(commandParameters, dataRow);

2388 

2389         return SqlHelper.ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName, commandParameters);

2390       }

2391       else

2392       {

2393         return SqlHelper.ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName);

2394       }

2395     }

2396     #endregion

2397 

2398   }

2399 

2400   /// <summary>

2401   /// SqlHelperParameterCache provides functions to leverage a static cache of procedure parameters, and the

2402   /// ability to discover parameters for stored procedures at run-time.

2403   /// </summary>

2404   public sealed class SqlHelperParameterCache

2405   {

2406     #region private methods, variables, and constructors

2407 

2408     //Since this class provides only static methods, make the default constructor private to prevent 

2409     //instances from being created with "new SqlHelperParameterCache()"

2410     private SqlHelperParameterCache() { }

2411 

2412     private static Hashtable paramCache = Hashtable.Synchronized(new Hashtable());

2413 

2414     /// <summary>

2415     /// Resolve at run time the appropriate set of SqlParameters for a stored procedure

2416     /// </summary>

2417     /// <param name="connection">A valid SqlConnection object</param>

2418     /// <param name="spName">The name of the stored procedure</param>

2419     /// <param name="includeReturnValueParameter">Whether or not to include their return value parameter</param>

2420     /// <returns>The parameter array discovered.</returns>

2421     private static SqlParameter[] DiscoverSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter)

2422     {

2423       if (connection == null) throw new ArgumentNullException("connection");

2424       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2425 

2426       SqlCommand cmd = new SqlCommand(spName, connection);

2427       cmd.CommandType = CommandType.StoredProcedure;

2428 

2429       connection.Open();

2430       SqlCommandBuilder.DeriveParameters(cmd);

2431       connection.Close();

2432 

2433       if (!includeReturnValueParameter)

2434       {

2435         cmd.Parameters.RemoveAt(0);

2436       }

2437 

2438       SqlParameter[] discoveredParameters = new SqlParameter[cmd.Parameters.Count];

2439 

2440       cmd.Parameters.CopyTo(discoveredParameters, 0);

2441 

2442       // Init the parameters with a DBNull value

2443       foreach (SqlParameter discoveredParameter in discoveredParameters)

2444       {

2445         discoveredParameter.Value = DBNull.Value;

2446       }

2447       return discoveredParameters;

2448     }

2449 

2450     /// <summary>

2451     /// Deep copy of cached SqlParameter array

2452     /// </summary>

2453     /// <param name="originalParameters"></param>

2454     /// <returns></returns>

2455     private static SqlParameter[] CloneParameters(SqlParameter[] originalParameters)

2456     {

2457       SqlParameter[] clonedParameters = new SqlParameter[originalParameters.Length];

2458 

2459       for (int i = 0, j = originalParameters.Length; i < j; i++)

2460       {

2461         clonedParameters[i] = (SqlParameter)((ICloneable)originalParameters[i]).Clone();

2462       }

2463 

2464       return clonedParameters;

2465     }

2466 

2467     #endregion private methods, variables, and constructors

2468 

2469     #region caching functions

2470 

2471     /// <summary>

2472     /// Add parameter array to the cache

2473     /// </summary>

2474     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

2475     /// <param name="commandText">The stored procedure name or T-SQL command</param>

2476     /// <param name="commandParameters">An array of SqlParamters to be cached</param>

2477     public static void CacheParameterSet(string connectionString, string commandText, params SqlParameter[] commandParameters)

2478     {

2479       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

2480       if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");

2481 

2482       string hashKey = connectionString + ":" + commandText;

2483 

2484       paramCache[hashKey] = commandParameters;

2485     }

2486 

2487     /// <summary>

2488     /// Retrieve a parameter array from the cache

2489     /// </summary>

2490     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

2491     /// <param name="commandText">The stored procedure name or T-SQL command</param>

2492     /// <returns>An array of SqlParamters</returns>

2493     public static SqlParameter[] GetCachedParameterSet(string connectionString, string commandText)

2494     {

2495       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

2496       if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");

2497 

2498       string hashKey = connectionString + ":" + commandText;

2499 

2500       SqlParameter[] cachedParameters = paramCache[hashKey] as SqlParameter[];

2501       if (cachedParameters == null)

2502       {

2503         return null;

2504       }

2505       else

2506       {

2507         return CloneParameters(cachedParameters);

2508       }

2509     }

2510 

2511     #endregion caching functions

2512 

2513     #region Parameter Discovery Functions

2514 

2515     /// <summary>

2516     /// Retrieves the set of SqlParameters appropriate for the stored procedure

2517     /// </summary>

2518     /// <remarks>

2519     /// This method will query the database for this information, and then store it in a cache for future requests.

2520     /// </remarks>

2521     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

2522     /// <param name="spName">The name of the stored procedure</param>

2523     /// <returns>An array of SqlParameters</returns>

2524     public static SqlParameter[] GetSpParameterSet(string connectionString, string spName)

2525     {

2526       return GetSpParameterSet(connectionString, spName, false);

2527     }

2528 

2529     /// <summary>

2530     /// Retrieves the set of SqlParameters appropriate for the stored procedure

2531     /// </summary>

2532     /// <remarks>

2533     /// This method will query the database for this information, and then store it in a cache for future requests.

2534     /// </remarks>

2535     /// <param name="connectionString">A valid connection string for a SqlConnection</param>

2536     /// <param name="spName">The name of the stored procedure</param>

2537     /// <param name="includeReturnValueParameter">A bool value indicating whether the return value parameter should be included in the results</param>

2538     /// <returns>An array of SqlParameters</returns>

2539     public static SqlParameter[] GetSpParameterSet(string connectionString, string spName, bool includeReturnValueParameter)

2540     {

2541       if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

2542       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2543 

2544       using (SqlConnection connection = new SqlConnection(connectionString))

2545       {

2546         return GetSpParameterSetInternal(connection, spName, includeReturnValueParameter);

2547       }

2548     }

2549 

2550     /// <summary>

2551     /// Retrieves the set of SqlParameters appropriate for the stored procedure

2552     /// </summary>

2553     /// <remarks>

2554     /// This method will query the database for this information, and then store it in a cache for future requests.

2555     /// </remarks>

2556     /// <param name="connection">A valid SqlConnection object</param>

2557     /// <param name="spName">The name of the stored procedure</param>

2558     /// <returns>An array of SqlParameters</returns>

2559     internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName)

2560     {

2561       return GetSpParameterSet(connection, spName, false);

2562     }

2563 

2564     /// <summary>

2565     /// Retrieves the set of SqlParameters appropriate for the stored procedure

2566     /// </summary>

2567     /// <remarks>

2568     /// This method will query the database for this information, and then store it in a cache for future requests.

2569     /// </remarks>

2570     /// <param name="connection">A valid SqlConnection object</param>

2571     /// <param name="spName">The name of the stored procedure</param>

2572     /// <param name="includeReturnValueParameter">A bool value indicating whether the return value parameter should be included in the results</param>

2573     /// <returns>An array of SqlParameters</returns>

2574     internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter)

2575     {

2576       if (connection == null) throw new ArgumentNullException("connection");

2577       using (SqlConnection clonedConnection = (SqlConnection)((ICloneable)connection).Clone())

2578       {

2579         return GetSpParameterSetInternal(clonedConnection, spName, includeReturnValueParameter);

2580       }

2581     }

2582 

2583     /// <summary>

2584     /// Retrieves the set of SqlParameters appropriate for the stored procedure

2585     /// </summary>

2586     /// <param name="connection">A valid SqlConnection object</param>

2587     /// <param name="spName">The name of the stored procedure</param>

2588     /// <param name="includeReturnValueParameter">A bool value indicating whether the return value parameter should be included in the results</param>

2589     /// <returns>An array of SqlParameters</returns>

2590     private static SqlParameter[] GetSpParameterSetInternal(SqlConnection connection, string spName, bool includeReturnValueParameter)

2591     {

2592       if (connection == null) throw new ArgumentNullException("connection");

2593       if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

2594 

2595       string hashKey = connection.ConnectionString + ":" + spName + (includeReturnValueParameter ? ":include ReturnValue Parameter" : "");

2596 

2597       SqlParameter[] cachedParameters;

2598 

2599       cachedParameters = paramCache[hashKey] as SqlParameter[];

2600       if (cachedParameters == null)

2601       {

2602         SqlParameter[] spParameters = DiscoverSpParameterSet(connection, spName, includeReturnValueParameter);

2603         paramCache[hashKey] = spParameters;

2604         cachedParameters = spParameters;

2605       }

2606 

2607       return CloneParameters(cachedParameters);

2608     }

2609 

2610     #endregion Parameter Discovery Functions

2611 

2612   }

2613 }

 

你可能感兴趣的:(help)