SqlHelper和SqlHelperParameterCache类

   1 // ===============================================================================
   2 // 本例程示范了SqlHelper和SqlHelperParameterCache类的执行.
   3 
   4 using System; 
   5 using System.Data;
   6 using System.Xml;
   7 using System.Data.SqlClient;
   8 using System.Collections;
   9 
  10 namespace Microsoft.ApplicationBlocks.Data
  11 {
  12     /// <summary>    
  13         /// SqlHelper类意在综合SqlClient一般使用中的高性能和最好的应用能力.
  14     /// </summary>
  15     public sealed class SqlHelper
  16     {
  17         #region private utility methods & constructors
  18 
  19         // Since this class provides only static methods, make the default constructor private to prevent 
  20         // instances from being created with "new SqlHelper()"
  21         // 因为本类只提供静态方法,从而使得默认的私有构建器(constructor)防止由"new SqlHelper()"来创建实例.
  22 
  23         private SqlHelper() {}
  24 
  25         /// <summary>
  26         /// This method is used to attach array of SqlParameters to a SqlCommand.
  27         /// 
  28         /// 本方法用于将SqlParameters参数集赋予SqlCommand.
  29         /// This method will assign a value of DbNull to any parameter with a direction of
  30         /// InputOutput and a value of null.  
  31         /// 本方法将一个DbNull值赋予任意的具有输入输出方向和null值的参数.
  32         /// 
  33         /// This behavior will prevent default values from being used, but
  34         /// this will be the less common case than an intended pure output parameter (derived as InputOutput)
  35         /// where the user provided no input value.
  36         /// 这样就可以避免默认值被使用,但是更多的情况是用户有意只提供输出参数而不提供输入值.
  37         /// 
  38         /// </summary>
  39         /// <param name="command">The command to which the parameters will be added</param>
  40         /// <param name="command">将被赋予参数的命令</param>
  41         /// 
  42         /// <param name="commandParameters">An array of SqlParameters to be added to command</param>
  43         /// <param name="commandParameters">将被赋予命令的SqlParameters参数集</param>
  44         /// 
  45         private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters)
  46         {
  47             if( command == null ) throw new ArgumentNullException( "command" );
  48             if( commandParameters != null )
  49             {
  50                 foreach (SqlParameter p in commandParameters)
  51                 {
  52                     if( p != null )
  53                     {
  54                         // Check for derived output value with no value assigned
  55                                                 // 检测没有被赋值的输出值
  56                         if ( ( p.Direction == ParameterDirection.InputOutput || 
  57                             p.Direction == ParameterDirection.Input ) && 
  58                             (p.Value == null))
  59                         {
  60                             p.Value = DBNull.Value;
  61                         }
  62                         command.Parameters.Add(p);
  63                     }
  64                 }
  65             }
  66         }
  67 
  68         /// <summary>
  69         /// This method assigns dataRow column values to an array of SqlParameters
  70         /// 本方法将dataRow的列值赋予SqlParameters参数集
  71         /// </summary>
  72         /// <param name="commandParameters">Array of SqlParameters to be assigned values</param>
  73         /// <param name="commandParameters">将被赋值的SqlParameters参数集</param>
  74         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values</param>
  75         /// <param name="dataRow">用于维持已有程序参数值的dataRow</param>
  76         private static void AssignParameterValues(SqlParameter[] commandParameters, DataRow dataRow)
  77         {
  78             if ((commandParameters == null) || (dataRow == null)) 
  79             {
  80                 // Do nothing if we get no data
  81                 // 如果未得到数据则什么也不做
  82                 return;
  83             }
  84 
  85             int i = 0;
  86             // Set the parameters values
  87             // 给参数赋值
  88             foreach(SqlParameter commandParameter in commandParameters)
  89             {
  90                 // Check the parameter name
  91                 // 检测参数名称
  92                 if( commandParameter.ParameterName == null || 
  93                     commandParameter.ParameterName.Length <= 1 )
  94                     throw new Exception( 
  95                         string.Format( 
  96                             "Please provide a valid parameter name on the parameter #{0}, the ParameterName property has the following value: '{1}'.", 
  97                             i, commandParameter.ParameterName ) );
  98                 if (dataRow.Table.Columns.IndexOf(commandParameter.ParameterName.Substring(1)) != -1)
  99                     commandParameter.Value = dataRow[commandParameter.ParameterName.Substring(1)];
 100                 i++;
 101             }
 102         }
 103 
 104         /// <summary>
 105         /// This method assigns an array of values to an array of SqlParameters
 106         /// 本方法将一组值赋予SqlParameters参数集
 107         /// </summary>
 108         /// <param name="commandParameters">Array of SqlParameters to be assigned values</param>
 109         /// <param name="commandParameters">将被赋值的SqlParameters参数集</param>
 110         /// <param name="parameterValues">Array of objects holding the values to be assigned</param>
 111         /// <param name="parameterValues">持有用于分配的值的对象集</param>
 112         private static void AssignParameterValues(SqlParameter[] commandParameters, object[] parameterValues)
 113         {
 114             if ((commandParameters == null) || (parameterValues == null)) 
 115             {
 116                 // Do nothing if we get no data
 117                 // 如果未得到数据则什么也不做
 118                 return;
 119             }
 120 
 121             // We must have the same number of values as we pave parameters to put them in
 122             // 值的数目必须和参数的数目一致
 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             // 以SqlParameters参数迭代,分配值集中相应位置的值
 131             for (int i = 0, j = commandParameters.Length; i < j; i++)
 132             {
 133                 // If the current array value derives from IDbDataParameter, then assign its Value property
 134                 // 如果当前值集由IDbDataParameter导出,则分配其值属性
 135                 if (parameterValues[i] is IDbDataParameter)
 136                 {
 137                     IDbDataParameter paramInstance = (IDbDataParameter)parameterValues[i];
 138                     if( paramInstance.Value == null )
 139                     {
 140                         commandParameters[i].Value = DBNull.Value; 
 141                     }
 142                     else
 143                     {
 144                         commandParameters[i].Value = paramInstance.Value;
 145                     }
 146                 }
 147                 else if (parameterValues[i] == null)
 148                 {
 149                     commandParameters[i].Value = DBNull.Value;
 150                 }
 151                 else
 152                 {
 153                     commandParameters[i].Value = parameterValues[i];
 154                 }
 155             }
 156         }
 157 
 158         /// <summary>
 159         /// This method opens (if necessary) and assigns a connection, transaction, command type and parameters 
 160         /// to the provided command
 161         /// 本方法打开(若需要)并分配一个连接、事务、命令种类及参数给所提供的命令
 162         /// </summary>
 163         /// <param name="command">The SqlCommand to be prepared</param>
 164         /// <param name="command">准备SqlCommand命令</param>
 165         /// 
 166         /// <param name="connection">A valid SqlConnection, on which to execute this command</param>
 167         /// <param name="connection">合法的SQL连接,用于在其上执行命令</param>
 168         /// 
 169         /// <param name="transaction">A valid SqlTransaction, or 'null'</param>
 170         /// <param name="transaction">合法的SQL事务(SqlTransaction), 或'null'</param>
 171         /// 
 172         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
 173         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
 174         /// 
 175         /// <param name="commandText">The stored procedure name or T-SQL command</param>
 176         /// <param name="commandText">存储过程名称或T-SQL命令</param>
 177         /// 
 178         /// <param name="commandParameters">An array of SqlParameters to be associated with the command or 'null' if no parameters are required</param>
 179         /// <param name="commandParameters">与命令关联的SqlParameters参数集,如果不需要参数,则为空'null'</param>
 180         /// 
 181         /// <param name="mustCloseConnection"><c>true</c> if the connection was opened by the method, otherwose is false.</param>
 182         /// <param name="mustCloseConnection">如果连接由方法打开,为true,否则为false.</param>
 183         /// 
 184         private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, out bool mustCloseConnection )
 185         {
 186             if( command == null ) throw new ArgumentNullException( "command" );
 187             if( commandText == null || commandText.Length == 0 ) throw new ArgumentNullException( "commandText" );
 188 
 189             // If the provided connection is not open, we will open it
 190             // 如果提供的连接没有打开,则打开它
 191             if (connection.State != ConnectionState.Open)
 192             {
 193                 mustCloseConnection = true;
 194                 connection.Open();
 195             }
 196             else
 197             {
 198                 mustCloseConnection = false;
 199             }
 200 
 201             // Associate the connection with the command
 202             // 将连接与命令相关联
 203             command.Connection = connection;
 204 
 205             // Set the command text (stored procedure name or SQL statement)
 206             // 设置命令文本(存储过程名或SQL描述)
 207             command.CommandText = commandText;
 208 
 209             // If we were provided a transaction, assign it
 210             // 如果提供有事务(transaction),配置它
 211             if (transaction != null)
 212             {
 213                 if( transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
 214                 command.Transaction = transaction;
 215             }
 216 
 217             // Set the command type
 218             // 设置命令类型
 219             command.CommandType = commandType;
 220 
 221             // Attach the command parameters if they are provided
 222             // 命令参数提供后,将它们附上
 223             if (commandParameters != null)
 224             {
 225                 AttachParameters(command, commandParameters);
 226             }
 227             return;
 228         }
 229 
 230         #endregion private utility methods & constructors
 231 
 232         #region ExecuteNonQuery
 233 
 234         /// <summary>
 235         /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the database specified in 
 236         /// the connection string
 237         /// 执行SQL命令(无返回值且不需要参数)以取代由连接字符串指定的数据库
 238         /// </summary>
 239         /// <remarks>
 240         /// e.g.:
 241         /// 例子:  
 242         ///  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders");
 243         /// </remarks>
 244         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
 245         /// <param name="connectionString">为SQL连接提供的合法的连接字符串</param>
 246         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
 247         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
 248         /// <param name="commandText">The stored procedure name or T-SQL command</param>
 249         /// <param name="commandText">存储过程名称或T-SQL命令</param>
 250         /// <returns>An int representing the number of rows affected by the command</returns>
 251         /// <returns>返回一个整型数,表示由命令影响的行数</returns>
 252         public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText)
 253         {
 254             // Pass through the call providing null for the set of SqlParameters
 255             // 将给SqlParameters参数集赋空值的调用传递
 256             return ExecuteNonQuery(connectionString, commandType, commandText, (SqlParameter[])null);
 257         }
 258 
 259         /// <summary>
 260         /// Execute a SqlCommand (that returns no resultset) against the database specified in the connection string 
 261         /// using the provided parameters
 262         /// 利用提供的参数值,执行SQL命令(不返回结果集)以取代由连接字符串指定的数据库.
 263         /// </summary>
 264         /// <remarks>
 265         /// e.g.:
 266         /// 例:
 267         ///  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
 268         /// </remarks>
 269         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
 270         /// <param name="connectionString">为SQL连接提供的合法的连接字符串</param>
 271         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
 272         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
 273         /// <param name="commandText">The stored procedure name or T-SQL command</param>
 274         /// <param name="commandText">存储过程名称或T-SQL命令</param>
 275         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
 276         /// <param name="commandParameters">用于执行SQL命令的SqlParamters参数集</param>
 277         /// <returns>An int representing the number of rows affected by the command</returns>
 278         /// <returns>返回一个整型数,表示由命令影响的行数</returns>
 279         public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 280         {
 281             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
 282 
 283             // Create & open a SqlConnection, and dispose of it after we are done
 284             // 创建并打开一个SQL连接,并在使用完后清除(dispose)
 285             using (SqlConnection connection = new SqlConnection(connectionString))
 286             {
 287                 connection.Open();
 288 
 289                 // Call the overload that takes a connection in place of the connection string
 290                 // 调用一个用于连接的过载(overload)来代替连接字符串
 291                 return ExecuteNonQuery(connection, commandType, commandText, commandParameters);
 292             }
 293         }
 294 
 295         /// <summary>
 296         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the database specified in 
 297         /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
 298         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
 299         /// 利用提供的参数值,通过SQL命令(不返回结果集)执行存储过程以取代由连接字符串指定的数据库.
 300         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
 301         /// </summary>
 302         /// <remarks>
 303         /// This method provides no access to output parameters or the stored procedure's return value parameter.
 304         /// 此方法不能获取输出参数或存储过程的返回值参数.
 305         /// e.g.:  
 306         /// 例:
 307         ///  int result = ExecuteNonQuery(connString, "PublishOrders", 24, 36);
 308         /// </remarks>
 309         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
 310         /// <param name="connectionString">为SQL连接提供的合法的连接字符串</param>
 311         /// <param name="spName">The name of the stored prcedure</param>
 312         /// <param name="spName">存储过程的名称</param>
 313         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
 314         /// <param name="parameterValues">分配为所存储过程的输入值的对象集</param>
 315         /// <returns>An int representing the number of rows affected by the command</returns>
 316         /// <returns>返回一个整型数,表示由命令影响的行数</returns>
 317         public static int ExecuteNonQuery(string connectionString, string spName, params object[] parameterValues)
 318         {
 319             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
 320             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
 321 
 322             // If we receive parameter values, we need to figure out where they go
 323             // 如果收到参数值,则需要指出它们的去向
 324             if ((parameterValues != null) && (parameterValues.Length > 0)) 
 325             {
 326                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
 327                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
 328                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
 329 
 330                 // Assign the provided values to these parameters based on parameter order
 331                 // 依据参数顺序给他们赋值
 332                 AssignParameterValues(commandParameters, parameterValues);
 333 
 334                 // Call the overload that takes an array of SqlParameters
 335                 // 调用获取SqlParameters参数集的过载
 336                 return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters);
 337             }
 338             else 
 339             {
 340                 // Otherwise we can just call the SP without params
 341                                 // 否则只能调用无参数的SP
 342                 return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName);
 343             }
 344         }
 345 
 346         /// <summary>
 347         /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the provided SqlConnection. 
 348         /// 执行SQL命令(无返回值且不需要参数)以取代已有的SQL连接
 349         /// </summary>
 350         /// <remarks>
 351         /// e.g.:  
 352         /// 例:
 353         ///  int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders");
 354         /// </remarks>
 355         /// <param name="connection">A valid SqlConnection</param>
 356         /// <param name="connection">合法的SQL连接</param>
 357         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
 358         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
 359         /// <param name="commandText">The stored procedure name or T-SQL command</param>
 360         /// <param name="commandText">存储过程名称或T-SQL命令</param>
 361         /// <returns>An int representing the number of rows affected by the command</returns>
 362         /// <returns>返回一个整型数,表示由命令影响的行数</returns>
 363         public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText)
 364         {
 365             // Pass through the call providing null for the set of SqlParameters
 366             // 将给SqlParameters参数集赋空值的调用传递
 367             return ExecuteNonQuery(connection, commandType, commandText, (SqlParameter[])null);
 368         }
 369 
 370         /// <summary>
 371         /// Execute a SqlCommand (that returns no resultset) against the specified SqlConnection 
 372         /// using the provided parameters.
 373         /// 执行SQL命令(不返回结果集)以取代由所提供的参数指定的SQL连接.
 374         /// </summary>
 375         /// <remarks>
 376         /// e.g.:  
 377         /// 例:
 378         ///  int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
 379         /// </remarks>
 380         /// <param name="connection">A valid SqlConnection</param>
 381         /// <param name="connection">合法的SQL连接</param>
 382         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
 383         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
 384         /// <param name="commandText">The stored procedure name or T-SQL command</param>
 385         /// <param name="commandText">存储过程名称或T-SQL命令</param>
 386         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
 387         /// <param name="commandParameters">用于执行命令的SqlParamters参数集</param>
 388         /// <returns>An int representing the number of rows affected by the command</returns>
 389         /// <returns>返回一个整型数,表示由命令影响的行数</returns>
 390         public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 391         {    
 392             if( connection == null ) throw new ArgumentNullException( "connection" );
 393 
 394             // Create a command and prepare it for execution
 395             // 创建一个用于执行的命令
 396             SqlCommand cmd = new SqlCommand();
 397             bool mustCloseConnection = false;
 398             PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection );
 399             
 400             // Finally, execute the command
 401             // 执行此命令
 402             int retval = cmd.ExecuteNonQuery();
 403             
 404             // Detach the SqlParameters from the command object, so they can be used again
 405             // 将SqlParameters从命令对象中分离,以便再次使用
 406             cmd.Parameters.Clear();
 407             if( mustCloseConnection )
 408                 connection.Close();
 409             return retval;
 410         }
 411 
 412         /// <summary>
 413         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified SqlConnection 
 414         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
 415         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
 416         /// 利用提供的参数值,通过SQL命令(不返回结果集)执行存储过程以取代由连接字符串指定的数据库.
 417         /// 此方法查询数据库以发现用于存储过程参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
 418         /// </summary>
 419         /// <remarks>
 420         /// This method provides no access to output parameters or the stored procedure's return value parameter.
 421         /// 此方法不能获取输出参数或存储过程的返回值参数.
 422         /// e.g.:  
 423         /// 例:
 424         ///  int result = ExecuteNonQuery(conn, "PublishOrders", 24, 36);
 425         /// </remarks>
 426         /// <param name="connection">A valid SqlConnection</param>
 427         /// <param name="connection">合法的SQL连接</param>
 428         /// <param name="spName">The name of the stored procedure</param>
 429         /// <param name="spName">存储过程的名称</param>
 430         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
 431         /// <param name="parameterValues">作为存储过程的输入值对象集</param>
 432         /// <returns>An int representing the number of rows affected by the command</returns>
 433         /// <returns>返回一个整型数,表示由命令影响的行数</returns>
 434         public static int ExecuteNonQuery(SqlConnection connection, string spName, params object[] parameterValues)
 435         {
 436             if( connection == null ) throw new ArgumentNullException( "connection" );
 437             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
 438 
 439             // If we receive parameter values, we need to figure out where they go
 440             // 如果收到参数值,则需要指出它们的去向
 441             if ((parameterValues != null) && (parameterValues.Length > 0)) 
 442             {
 443                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
 444                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
 445                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
 446 
 447                 // Assign the provided values to these parameters based on parameter order
 448                 // 依据参数顺序给他们赋值
 449                 AssignParameterValues(commandParameters, parameterValues);
 450 
 451                 // Call the overload that takes an array of SqlParameters
 452                 // 调用获取SqlParameters参数集的过载
 453                 return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName, commandParameters);
 454             }
 455             else 
 456             {
 457                 // Otherwise we can just call the SP without params
 458                                 // 否则只能调用无参数的SP
 459                 return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName);
 460             }
 461         }
 462 
 463         /// <summary>
 464         /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the provided SqlTransaction. 
 465         /// 执行SQL命令(无返回值且不需要参数)以取代已有的SQL事务.
 466         /// </summary>
 467         /// <remarks>
 468         /// e.g.:  
 469         /// 例:
 470         ///  int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "PublishOrders");
 471         /// </remarks>
 472         /// <param name="transaction">A valid SqlTransaction</param>
 473         /// <param name="connection">合法的SQL连接</param>
 474         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
 475         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
 476         /// <param name="commandText">The stored procedure name or T-SQL command</param>
 477         /// <param name="commandText">存储过程名称或T-SQL命令</param>
 478         /// <returns>An int representing the number of rows affected by the command</returns>
 479         /// <returns>返回一个整型数,表示由命令影响的行数</returns>
 480         public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText)
 481         {
 482             // Pass through the call providing null for the set of SqlParameters
 483             // 将给SqlParameters参数集赋空值的调用传递
 484             return ExecuteNonQuery(transaction, commandType, commandText, (SqlParameter[])null);
 485         }
 486 
 487         /// <summary>
 488         /// Execute a SqlCommand (that returns no resultset) against the specified SqlTransaction
 489         /// using the provided parameters.
 490         /// 执行SQL命令(不返回结果集)以取代由所提供的参数指定的SQL事务.
 491         /// </summary>
 492         /// <remarks>
 493         /// e.g.:  
 494         /// 例:
 495         ///  int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
 496         /// </remarks>
 497         /// <param name="transaction">A valid SqlTransaction</param>
 498         /// <param name="connection">合法的SQL连接</param>
 499         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
 500         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
 501         /// <param name="commandText">The stored procedure name or T-SQL command</param>
 502         /// <param name="commandText">存储过程名称或T-SQL命令</param>
 503         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
 504         /// <param name="commandParameters">用于执行命令的SqlParamters参数集</param>
 505         /// <returns>An int representing the number of rows affected by the command</returns>
 506         /// <returns>返回一个整型数,表示由命令影响的行数</returns>
 507         public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 508         {
 509             if( transaction == null ) throw new ArgumentNullException( "transaction" );
 510             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
 511 
 512             // Create a command and prepare it for execution
 513                        // 创建一个用于执行的命令
 514             SqlCommand cmd = new SqlCommand();
 515             bool mustCloseConnection = false;
 516             PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection );
 517                 
 518             // Finally, execute the command
 519                        // 执行此命令
 520             int retval = cmd.ExecuteNonQuery();
 521                 
 522             // Detach the SqlParameters from the command object, so they can be used again
 523                         // 将SqlParameters从命令对象中分离,以便再次使用
 524             cmd.Parameters.Clear();
 525             return retval;
 526         }
 527 
 528         /// <summary>
 529         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified 
 530         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
 531         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
 532         /// 利用提供的参数值,通过SQL命令(不返回结果集)执行存储过程以取代指定的SQL事务.
 533         /// 此方法查询数据库以发现用于存储过程参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
 534         /// </summary>
 535         /// <remarks>
 536         /// This method provides no access to output parameters or the stored procedure's return value parameter.
 537         /// 此方法不能获取输出参数或存储过程的返回值参数.
 538         /// e.g.:  
 539         /// 例:
 540         ///  int result = ExecuteNonQuery(conn, trans, "PublishOrders", 24, 36);
 541         /// </remarks>
 542         /// <param name="transaction">A valid SqlTransaction</param>
 543         /// <param name="connection">合法的SQL连接</param>
 544         /// <param name="spName">The name of the stored procedure</param>
 545         /// <param name="commandText">存储过程名称</param>
 546         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
 547         /// <param name="parameterValues">作为存储过程的输入值对象集</param>
 548         /// <returns>An int representing the number of rows affected by the command</returns>
 549         /// <returns>返回一个整型数,表示由命令影响的行数</returns>
 550         public static int ExecuteNonQuery(SqlTransaction transaction, string spName, params object[] parameterValues)
 551         {
 552             if( transaction == null ) throw new ArgumentNullException( "transaction" );
 553             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
 554             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
 555 
 556             // If we receive parameter values, we need to figure out where they go
 557                        // 如果收到参数值,则需要指出它们的去向
 558             if ((parameterValues != null) && (parameterValues.Length > 0)) 
 559             {
 560                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
 561                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
 562                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
 563 
 564                 // Assign the provided values to these parameters based on parameter order
 565                 // 依据参数顺序给他们赋值
 566                 AssignParameterValues(commandParameters, parameterValues);
 567 
 568                 // Call the overload that takes an array of SqlParameters
 569                 // 调用获取SqlParameters参数集的过载
 570                 return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName, commandParameters);
 571             }
 572             else 
 573             {
 574                 // Otherwise we can just call the SP without params
 575                                 // 否则只能调用无参数的SP
 576                 return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName);
 577             }
 578         }
 579 
 580         #endregion ExecuteNonQuery
 581 
 582         #region ExecuteDataset
 583 
 584         /// <summary>
 585         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in 
 586         /// the connection string. 
 587         /// 执行SQL命令(有一个返回值且不需要参数)以取代由连接字符串指定的数据库.
 588         /// </summary>
 589         /// <remarks>
 590         /// e.g.:  
 591         /// 例:
 592         ///  DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders");
 593         /// </remarks>
 594         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
 595         /// <param name="connectionString">一个合法的为SQL连接使用的连接字符串</param>
 596         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
 597         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
 598         /// <param name="commandText">The stored procedure name or T-SQL command</param>
 599         /// <param name="commandText">存储过程名称或T-SQL命令</param>
 600         /// <returns>A dataset containing the resultset generated by the command</returns>
 601         /// <returns>返回一个包含由命令生成的结果集的数据集(dataset)</returns>
 602         public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText)
 603         {
 604             // Pass through the call providing null for the set of SqlParameters
 605             // 将给SqlParameters参数集赋空值的调用传递
 606             return ExecuteDataset(connectionString, commandType, commandText, (SqlParameter[])null);
 607         }
 608 
 609         /// <summary>
 610         /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string 
 611         /// using the provided parameters.
 612         /// 利用提供的参数,执行SQL命令(返回一个结果集)以取代由连接字符串指定的数据库.
 613         /// </summary>
 614         /// <remarks>
 615         /// e.g.:  
 616         /// 例:
 617         ///  DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
 618         /// </remarks>
 619         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
 620         /// <param name="connectionString">一个合法的为SQL连接使用的连接字符串</param>
 621         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
 622         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
 623         /// <param name="commandText">The stored procedure name or T-SQL command</param>
 624         /// <param name="commandText">存储过程名称或T-SQL命令</param>
 625         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
 626         /// <param name="commandParameters">用于执行命令的SqlParamters参数集</param>
 627         /// <returns>A dataset containing the resultset generated by the command</returns>
 628         /// <returns>返回一个包含由命令生成的结果集的数据集(dataset)</returns>
 629         public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 630         {
 631             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
 632 
 633             // Create & open a SqlConnection, and dispose of it after we are done
 634             // 创建并打开一个SQL连接,并在使用完后清除(dispose)
 635             using (SqlConnection connection = new SqlConnection(connectionString))
 636             {
 637                 connection.Open();
 638 
 639                 // Call the overload that takes a connection in place of the connection string
 640                 // 调用一个用于连接的过载(overload)来代替连接字符串
 641                 return ExecuteDataset(connection, commandType, commandText, commandParameters);
 642             }
 643         }
 644 
 645         /// <summary>
 646         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 
 647         /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
 648         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
 649         /// 利用提供的参数值,通过SQL命令(返回一个结果集)执行存储过程以取代在连接字符串中指定的数据库.
 650         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
 651         /// </summary>
 652         /// <remarks>
 653         /// This method provides no access to output parameters or the stored procedure's return value parameter.
 654         /// 此方法不能获取输出参数或存储过程的返回值参数.
 655         /// e.g.:  
 656         /// 例:
 657         ///  DataSet ds = ExecuteDataset(connString, "GetOrders", 24, 36);
 658         /// </remarks>
 659         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
 660         /// <param name="connectionString">一个合法的为SQL连接使用的连接字符串</param>
 661         /// <param name="spName">The name of the stored procedure</param>
 662         /// <param name="spName">存储过程名称</param>
 663         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
 664         /// <param name="parameterValues">分配为存储过程的输入值的对象集</param>
 665         /// <returns>A dataset containing the resultset generated by the command</returns>
 666         /// <returns>返回一个包含由命令生成的结果集的数据集(dataset)</returns>
 667         public static DataSet ExecuteDataset(string connectionString, string spName, params object[] parameterValues)
 668         {
 669             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
 670             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
 671             
 672             // If we receive parameter values, we need to figure out where they go
 673                        // 如果收到参数值,则需要指出它们的去向
 674             if ((parameterValues != null) && (parameterValues.Length > 0)) 
 675             {
 676                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
 677                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
 678                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
 679 
 680                 // Assign the provided values to these parameters based on parameter order
 681                 // 依据参数顺序给他们赋值
 682                 AssignParameterValues(commandParameters, parameterValues);
 683 
 684                 // Call the overload that takes an array of SqlParameters
 685                 // 调用获取SqlParameters参数集的过载
 686                 return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName, commandParameters);
 687             }
 688             else 
 689             {
 690                 // Otherwise we can just call the SP without params
 691                                 // 否则只能调用无参数的SP
 692                 return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName);
 693             }
 694         }
 695 
 696         /// <summary>
 697         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. 
 698         /// 执行SQL命令(有一个返回值且不需要参数)以取代已有的SQL连接.
 699         /// </summary>
 700         /// <remarks>
 701         /// e.g.:  
 702         /// 例:
 703         ///  DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders");
 704         /// </remarks>
 705         /// <param name="connection">A valid SqlConnection</param>
 706         /// <param name="connection">一个合法的SQL连接</param>
 707         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
 708         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
 709         /// <param name="commandText">The stored procedure name or T-SQL command</param>
 710         /// <param name="commandText">存储过程名称或T-SQL命令</param>
 711         /// <returns>A dataset containing the resultset generated by the command</returns>
 712         /// <returns>返回一个包含由命令生成的结果集的数据集(dataset)</returns>
 713         public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText)
 714         {
 715             // Pass through the call providing null for the set of SqlParameters
 716             // 将给SqlParameters参数集赋空值的调用传递
 717             return ExecuteDataset(connection, commandType, commandText, (SqlParameter[])null);
 718         }
 719         
 720         /// <summary>
 721         /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 
 722         /// using the provided parameters.
 723         /// 利用提供的参数,执行SQL命令(返回一个结果集)以取代指定的SQL连接.
 724         /// </summary>
 725         /// <remarks>
 726         /// e.g.:  
 727         /// 例:
 728         ///  DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
 729         /// </remarks>
 730         /// <param name="connection">A valid SqlConnection</param>
 731         /// <param name="connection">一个合法的SQL连接</param>
 732         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
 733         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
 734         /// <param name="commandText">The stored procedure name or T-SQL command</param>
 735         /// <param name="commandText">存储过程名称或T-SQL命令</param>
 736         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
 737         /// <param name="commandParameters">用于执行命令的SqlParamters参数集</param>
 738         /// <returns>A dataset containing the resultset generated by the command</returns>
 739         /// <returns>返回一个包含由命令生成的结果集的数据集(dataset)</returns>
 740         public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 741         {
 742             if( connection == null ) throw new ArgumentNullException( "connection" );
 743 
 744             // Create a command and prepare it for execution
 745                         // 创建一个用于执行的命令
 746             SqlCommand cmd = new SqlCommand();
 747             bool mustCloseConnection = false;
 748             PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection );
 749                 
 750             // Create the DataAdapter & DataSet
 751                         // 创建DataAdapter和DataSet
 752             using( SqlDataAdapter da = new SqlDataAdapter(cmd) )
 753             {
 754                 DataSet ds = new DataSet();
 755 
 756                 // Fill the DataSet using default values for DataTable names, etc
 757                                 // 用为DataTable名称等设定的默认值填充DataSet对象集
 758                 da.Fill(ds);
 759                 
 760                 // Detach the SqlParameters from the command object, so they can be used again
 761                                 // 从命令对象中分离(Detach)SqlParameters,以便它们能再次使用
 762                 cmd.Parameters.Clear();
 763 
 764                 if( mustCloseConnection )
 765                     connection.Close();
 766 
 767                 // Return the dataset
 768                                 // 返回对象集
 769                 return ds;
 770             }    
 771         }
 772         
 773         /// <summary>
 774         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
 775         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
 776         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
 777         /// 利用提供的参数值,通过SQL命令(返回一个结果集)执行存储过程以取代指定的SQL连接.
 778         /// 此方法查询数据库以发现用于存储过程参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
 779         /// </summary>
 780         /// <remarks>
 781         /// This method provides no access to output parameters or the stored procedure's return value parameter.
 782         /// 此方法不能获取输出参数或存储过程的返回值参数.
 783         /// e.g.:  
 784         /// 例:
 785         ///  DataSet ds = ExecuteDataset(conn, "GetOrders", 24, 36);
 786         /// </remarks>
 787         /// <param name="connection">A valid SqlConnection</param>
 788         /// <param name="connection">一个合法的SQL连接</param>
 789         /// <param name="spName">The name of the stored procedure</param>
 790         /// <param name="spName">存储过程名称</param>
 791         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
 792         /// <param name="parameterValues">分配为存储过程的输入值的对象集</param>
 793         /// <returns>A dataset containing the resultset generated by the command</returns>
 794         /// <returns>返回一个包含由命令生成的结果集的数据集(dataset)</returns>
 795         public static DataSet ExecuteDataset(SqlConnection connection, string spName, params object[] parameterValues)
 796         {
 797             if( connection == null ) throw new ArgumentNullException( "connection" );
 798             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
 799 
 800             // If we receive parameter values, we need to figure out where they go
 801             // 如果收到参数值,则需要指出它们的去向
 802             if ((parameterValues != null) && (parameterValues.Length > 0)) 
 803             {
 804                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
 805                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
 806                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
 807 
 808                 // Assign the provided values to these parameters based on parameter order
 809                 // 依据参数顺序给他们赋值
 810                 AssignParameterValues(commandParameters, parameterValues);
 811 
 812                 // Call the overload that takes an array of SqlParameters
 813                 // 调用获取SqlParameters参数集的过载
 814                 return ExecuteDataset(connection, CommandType.StoredProcedure, spName, commandParameters);
 815             }
 816             else 
 817             {
 818                 // Otherwise we can just call the SP without params
 819                                 // 否则只能调用无参数的SP
 820                 return ExecuteDataset(connection, CommandType.StoredProcedure, spName);
 821             }
 822         }
 823 
 824         /// <summary>
 825         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. 
 826         /// 执行SQL命令(有一个返回值且不需要参数)以取代已有的SQL事务.
 827         /// </summary>
 828         /// <remarks>
 829         /// e.g.:  
 830         /// 例:
 831         ///  DataSet ds = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders");
 832         /// </remarks>
 833         /// <param name="transaction">A valid SqlTransaction</param>
 834         /// <param name="transaction">一个合法的SQL事务</param>
 835         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
 836         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
 837         /// <param name="commandText">The stored procedure name or T-SQL command</param>
 838         /// <param name="commandText">存储过程名称或T-SQL命令</param>
 839         /// <returns>A dataset containing the resultset generated by the command</returns>
 840         /// <returns>返回一个包含由命令生成的结果集的数据集(dataset)</returns>
 841         public static DataSet ExecuteDataset(SqlTransaction transaction, CommandType commandType, string commandText)
 842         {
 843             // Pass through the call providing null for the set of SqlParameters
 844             // 将给SqlParameters参数集赋空值的调用传递
 845             return ExecuteDataset(transaction, commandType, commandText, (SqlParameter[])null);
 846         }
 847         
 848         /// <summary>
 849         /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction
 850         /// using the provided parameters.
 851         /// 利用提供的参数,执行SQL命令(返回一个结果集)以取代指定的SQL事务.
 852         /// </summary>
 853         /// <remarks>
 854         /// e.g.:  
 855         /// 例:
 856         ///  DataSet ds = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
 857         /// </remarks>
 858         /// <param name="transaction">A valid SqlTransaction</param>
 859         /// <param name="transaction">一个合法的SQL事务</param>
 860         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
 861         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
 862         /// <param name="commandText">The stored procedure name or T-SQL command</param>
 863         /// <param name="commandText">存储过程名称或T-SQL命令</param>
 864         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
 865         /// <param name="commandParameters">用于执行命令的SqlParamters参数集</param>
 866         /// <returns>A dataset containing the resultset generated by the command</returns>
 867         /// <returns>返回一个包含由命令生成的结果集的数据集(dataset)</returns>
 868         public static DataSet ExecuteDataset(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 869         {
 870             if( transaction == null ) throw new ArgumentNullException( "transaction" );
 871             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
 872 
 873             // Create a command and prepare it for execution
 874                         // 创建一个用于执行的命令
 875             SqlCommand cmd = new SqlCommand();
 876             bool mustCloseConnection = false;
 877             PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection );
 878                 
 879             // Create the DataAdapter & DataSet
 880                         // 创建DataAdapter和DataSet
 881             using( SqlDataAdapter da = new SqlDataAdapter(cmd) )
 882             {
 883                 DataSet ds = new DataSet();
 884 
 885                 // Fill the DataSet using default values for DataTable names, etc
 886                                 // 用为DataTable名称等设定的默认值填充DataSet对象集
 887                 da.Fill(ds);
 888                 
 889                 // Detach the SqlParameters from the command object, so they can be used again
 890                                 // 从命令对象中分离(Detach)SqlParameters,以便它们能再次使用
 891                 cmd.Parameters.Clear();
 892 
 893                 // Return the dataset
 894                                 // 返回对象集
 895                 return ds;
 896             }    
 897         }
 898         
 899         /// <summary>
 900         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified 
 901         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
 902         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
 903         /// 利用提供的参数值,通过SQL命令(返回一个结果集)执行存储过程以取代指定的SQL事务.
 904         /// 此方法查询数据库以发现用于存储过程参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
 905         /// </summary>
 906         /// <remarks>
 907         /// This method provides no access to output parameters or the stored procedure's return value parameter.
 908         /// 此方法不能获取输出参数或存储过程的返回值参数.
 909         /// e.g.:  
 910         /// 例:
 911         ///  DataSet ds = ExecuteDataset(trans, "GetOrders", 24, 36);
 912         /// </remarks>
 913         /// <param name="transaction">A valid SqlTransaction</param>
 914         /// <param name="transaction">一个合法的SQL事务</param>
 915         /// <param name="spName">The name of the stored procedure</param>
 916         /// <param name="spName">存储过程名称</param>
 917         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
 918         /// <param name="parameterValues">分配为存储过程的输入值的对象集</param>
 919         /// <returns>A dataset containing the resultset generated by the command</returns>
 920         /// <returns>返回一个包含由命令生成的结果集的数据集(dataset)</returns>
 921         public static DataSet ExecuteDataset(SqlTransaction transaction, string spName, params object[] parameterValues)
 922         {
 923             if( transaction == null ) throw new ArgumentNullException( "transaction" );
 924             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
 925             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
 926             
 927             // If we receive parameter values, we need to figure out where they go
 928                         // 如果收到参数值,则需要指出它们的去向
 929             if ((parameterValues != null) && (parameterValues.Length > 0)) 
 930             {
 931                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
 932                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
 933                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
 934 
 935                 // Assign the provided values to these parameters based on parameter order
 936                 // 依据参数顺序给他们赋值
 937                 AssignParameterValues(commandParameters, parameterValues);
 938 
 939                 // Call the overload that takes an array of SqlParameters
 940                 // 调用获取SqlParameters参数集的过载
 941                 return ExecuteDataset(transaction, CommandType.StoredProcedure, spName, commandParameters);
 942             }
 943             else 
 944             {
 945                 // Otherwise we can just call the SP without params
 946                                 // 否则只能调用无参数的SP
 947                 return ExecuteDataset(transaction, CommandType.StoredProcedure, spName);
 948             }
 949         }
 950 
 951         #endregion ExecuteDataset
 952         
 953         #region ExecuteReader
 954 
 955         /// <summary>
 956         /// This enum is used to indicate whether the connection was provided by the caller, or created by SqlHelper, so that
 957         /// we can set the appropriate CommandBehavior when calling ExecuteReader()
 958         /// 这个计数器(enum)用来表明连接是由调用者提供,还是由SqlHelper创建,以便调用ExecuteReader()时设置适当的命令行为(CommandBehavior).
 959         /// </summary>
 960         private enum SqlConnectionOwnership    
 961         {
 962             /// <summary>Connection is owned and managed by SqlHelper</summary>
 963             /// <summary>连接由SqlHelper拥有并管理</summary>
 964             Internal, 
 965             /// <summary>Connection is owned and managed by the caller</summary>
 966             /// <summary>连接由调用者拥有并管理</summary>
 967             External
 968         }
 969 
 970         /// <summary>
 971         /// Create and prepare a SqlCommand, and call ExecuteReader with the appropriate CommandBehavior.
 972         /// 创建并准备一个命令,以适当的命令行为(CommandBehavior)调用ExecuteReader.
 973         /// </summary>
 974         /// <remarks>
 975         /// If we created and opened the connection, we want the connection to be closed when the DataReader is closed.
 976         /// 如果已经创建并打开了连接,当DataReader关闭时要相应关闭此连接.
 977         /// If the caller provided the connection, we want to leave it to them to manage.
 978         /// 如果是调用者提供的连接,将其留给调用者管理.
 979         /// </remarks>
 980         /// <param name="connection">A valid SqlConnection, on which to execute this command</param>
 981         /// <param name="connection">一个合法的用于执行命令的SQL连接</param>
 982         /// <param name="transaction">A valid SqlTransaction, or 'null'</param>
 983         /// <param name="transaction">一个合法的SQL事务,或为空'null'</param>
 984         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
 985         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
 986         /// <param name="commandText">The stored procedure name or T-SQL command</param>
 987         /// <param name="commandText">存储过程名称或T-SQL命令</param>
 988         /// <param name="commandParameters">An array of SqlParameters to be associated with the command or 'null' if no parameters are required</param>
 989         /// <param name="commandParameters">与命令相关联的SqlParamters参数集,如果不要求提供参数,则为空'null'</param>
 990         /// <param name="connectionOwnership">Indicates whether the connection parameter was provided by the caller, or created by SqlHelper</param>
 991         /// <param name="connectionOwnership">表明连接参数是由调用者提供还是由SqlHelper创建</param>
 992         /// <returns>SqlDataReader containing the results of the command</returns>
 993         /// <returns>包含命令结果的SqlDataReader</returns>
 994         private static SqlDataReader ExecuteReader(SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, SqlConnectionOwnership connectionOwnership)
 995         {    
 996             if( connection == null ) throw new ArgumentNullException( "connection" );
 997 
 998             bool mustCloseConnection = false;
 999             // Create a command and prepare it for execution
1000             // 创建一个用于执行的命令
1001             SqlCommand cmd = new SqlCommand();
1002             try
1003             {
1004                 PrepareCommand(cmd, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection );
1005             
1006                 // Create a reader
1007                                 // 创建一个reader
1008                 SqlDataReader dataReader;
1009 
1010                 // Call ExecuteReader with the appropriate CommandBehavior
1011                                 // 以适当的命令行为(CommandBehavior)调用ExecuteReader
1012                 if (connectionOwnership == SqlConnectionOwnership.External)
1013                 {
1014                     dataReader = cmd.ExecuteReader();
1015                 }
1016                 else
1017                 {
1018                     dataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
1019                 }
1020             
1021                 // Detach the SqlParameters from the command object, so they can be used again.
1022                                 // 从命令对象中分离(Detach)SqlParameters,以便它们能再次使用.
1023                 // HACK: There is a problem here, the output parameter values are fletched 
1024                 // when the reader is closed, so if the parameters are detached from the command
1025                 // then the SqlReader can磘 set its values. 
1026                 // When this happen, the parameters can磘 be used again in other command.
1027                                 // HACK: 这儿有一个问题:当reader关闭时,输出参数值被fletched,
1028                                 // 因此如果参数从命令中被分离,则SqlReader会设置它的值. 这时,参数就能被其他命令再次使用.
1029                 bool canClear = true;
1030                 foreach(SqlParameter commandParameter in cmd.Parameters)
1031                 {
1032                     if (commandParameter.Direction != ParameterDirection.Input)
1033                         canClear = false;
1034                 }
1035             
1036                 if (canClear)
1037                 {
1038                     cmd.Parameters.Clear();
1039                 }
1040 
1041                 return dataReader;
1042             }
1043             catch
1044             {
1045                 if( mustCloseConnection )
1046                     connection.Close();
1047                 throw;
1048             }
1049         }
1050 
1051         /// <summary>
1052         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in 
1053         /// the connection string. 
1054         /// 执行SQL命令(返回一个结果集且不需要参数)以取代在连接字符串中指定的数据库.
1055         /// </summary>
1056         /// <remarks>
1057         /// e.g.:  
1058         /// 例:
1059         ///  SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders");
1060         /// </remarks>
1061         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
1062         /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
1063         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1064         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1065         /// <param name="commandText">The stored procedure name or T-SQL command</param>
1066         /// <param name="commandText">存储过程名称或T-SQL命令</param>
1067         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
1068         /// <returns>返回一个包含由命令生成的结果集的SqlDataReader</returns>
1069         public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText)
1070         {
1071             // Pass through the call providing null for the set of SqlParameters
1072             // 将给SqlParameters参数集赋空值的调用传递
1073             return ExecuteReader(connectionString, commandType, commandText, (SqlParameter[])null);
1074         }
1075 
1076         /// <summary>
1077         /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string 
1078         /// using the provided parameters.
1079         /// 利用提供的参数,执行SQL命令(返回一个结果集)以取代在连接字符串中指定的数据库.
1080         /// </summary>
1081         /// <remarks>
1082         /// e.g.:  
1083         /// 例:
1084         ///  SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
1085         /// </remarks>
1086         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
1087         /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
1088         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1089         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1090         /// <param name="commandText">The stored procedure name or T-SQL command</param>
1091         /// <param name="commandText">存储过程名称或T-SQL命令</param>
1092         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
1093         /// <param name="commandParameters">一组用于执行命令的SqlParamters</param>
1094         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
1095         /// <returns>返回一个包含由命令生成的结果集的SqlDataReader</returns>
1096         public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
1097         {
1098             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
1099             SqlConnection connection = null;
1100             try
1101             {
1102                 connection = new SqlConnection(connectionString);
1103                 connection.Open();
1104 
1105                 // Call the private overload that takes an internally owned connection in place of the connection string
1106                 // 调用私有的过载(overload),以使内部的连接取代连接字符串
1107                 return ExecuteReader(connection, null, commandType, commandText, commandParameters,SqlConnectionOwnership.Internal);
1108             }
1109             catch
1110             {
1111                 // If we fail to return the SqlDatReader, we need to close the connection ourselves
1112                 // 如果返回SqlDatReader失败,则需要手工关闭连接
1113                 if( connection != null ) connection.Close();
1114                 throw;
1115             }
1116             
1117         }
1118 
1119         /// <summary>
1120         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 
1121         /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
1122         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
1123         /// 利用提供的参数值,通过SQL命令(返回一个结果集)执行存储过程以取代在连接字符串中指定的数据库.
1124         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
1125         /// </summary>
1126         /// <remarks>
1127         /// This method provides no access to output parameters or the stored procedure's return value parameter.
1128         /// 此方法不能获取输出参数或存储过程的返回值参数.
1129         /// e.g.:  
1130         /// 例:
1131         ///  SqlDataReader dr = ExecuteReader(connString, "GetOrders", 24, 36);
1132         /// </remarks>
1133         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
1134         /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
1135         /// <param name="spName">The name of the stored procedure</param>
1136         /// <param name="spName">存储过程的名称</param>
1137         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
1138         /// <param name="parameterValues">分配为存储过程的输入值的对象集</param>
1139         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
1140         /// <returns>返回一个包含由命令生成的结果集的SqlDataReader</returns>
1141         public static SqlDataReader ExecuteReader(string connectionString, string spName, params object[] parameterValues)
1142         {
1143             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
1144             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
1145             
1146             // If we receive parameter values, we need to figure out where they go
1147                         // 如果收到参数值,则需要指出它们的去向
1148             if ((parameterValues != null) && (parameterValues.Length > 0)) 
1149             {
1150                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
1151 
1152                 AssignParameterValues(commandParameters, parameterValues);
1153 
1154                 return ExecuteReader(connectionString, CommandType.StoredProcedure, spName, commandParameters);
1155             }
1156             else 
1157             {
1158                 // Otherwise we can just call the SP without params
1159                                 // 否则只能调用无参数的SP
1160                 return ExecuteReader(connectionString, CommandType.StoredProcedure, spName);
1161             }
1162         }
1163 
1164         /// <summary>
1165         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. 
1166         /// 执行SQL命令(有一个返回值且不需要参数)以取代已有的SQL连接.
1167         /// </summary>
1168         /// <remarks>
1169         /// e.g.:  
1170         /// 例:
1171         ///  SqlDataReader dr = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders");
1172         /// </remarks>
1173         /// <param name="connection">A valid SqlConnection</param>
1174         /// <param name="connection">一个合法的SQL连接</param>
1175         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1176         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1177         /// <param name="commandText">The stored procedure name or T-SQL command</param>
1178         /// <param name="commandText">存储过程名称或T-SQL命令</param>
1179         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
1180         /// <returns>返回一个包含由命令生成的结果集的SqlDataReader</returns>
1181         public static SqlDataReader ExecuteReader(SqlConnection connection, CommandType commandType, string commandText)
1182         {
1183             // Pass through the call providing null for the set of SqlParameters
1184             // 将给SqlParameters参数集赋空值的调用传递
1185             return ExecuteReader(connection, commandType, commandText, (SqlParameter[])null);
1186         }
1187 
1188         /// <summary>
1189         /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 
1190         /// using the provided parameters.
1191         /// 利用提供的参数,执行SQL命令(返回一个结果集)以取代指定的SQL连接.
1192         /// </summary>
1193         /// <remarks>
1194         /// e.g.:  
1195         /// 例:
1196         ///  SqlDataReader dr = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
1197         /// </remarks>
1198         /// <param name="connection">A valid SqlConnection</param>
1199         /// <param name="connection">一个合法的SQL连接</param>
1200         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1201         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1202         /// <param name="commandText">The stored procedure name or T-SQL command</param>
1203         /// <param name="commandText">存储过程名称或T-SQL命令</param>
1204         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
1205         /// <param name="commandParameters">一组用于执行命令的SqlParamters</param>
1206         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
1207         /// <returns>返回一个包含由命令生成的结果集的SqlDataReader</returns>
1208         public static SqlDataReader ExecuteReader(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
1209         {
1210             // Pass through the call to the private overload using a null transaction value and an externally owned connection
1211             // 用一个空事务值和一个外部的连接传递调用给私有的过载
1212             return ExecuteReader(connection, (SqlTransaction)null, commandType, commandText, commandParameters, SqlConnectionOwnership.External);
1213         }
1214 
1215         /// <summary>
1216         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
1217         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
1218         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
1219         /// 利用提供的参数值,通过SQL命令(返回一个结果集)执行存储过程以取代指定的SQL连接.
1220         /// 此方法查询数据库以发现用于存储过程参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
1221         /// </summary>
1222         /// <remarks>
1223         /// This method provides no access to output parameters or the stored procedure's return value parameter.
1224         /// 此方法不能获取输出参数或存储过程的返回值参数.
1225         /// e.g.:  
1226         /// 例:
1227         ///  SqlDataReader dr = ExecuteReader(conn, "GetOrders", 24, 36);
1228         /// </remarks>
1229         /// <param name="connection">A valid SqlConnection</param>
1230         /// <param name="connection">一个合法的SQL连接</param>
1231         /// <param name="spName">The name of the stored procedure</param>
1232         /// <param name="spName">存储过程名称</param>
1233         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
1234         /// <param name="parameterValues">分配为存储过程的输入值的对象集</param>
1235         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
1236         /// <returns>返回一个包含由命令生成的结果集的SqlDataReader</returns>
1237         public static SqlDataReader ExecuteReader(SqlConnection connection, string spName, params object[] parameterValues)
1238         {
1239             if( connection == null ) throw new ArgumentNullException( "connection" );
1240             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
1241 
1242             // If we receive parameter values, we need to figure out where they go
1243             // 如果收到参数值,则需要指出它们的去向
1244             if ((parameterValues != null) && (parameterValues.Length > 0)) 
1245             {
1246                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
1247 
1248                 AssignParameterValues(commandParameters, parameterValues);
1249 
1250                 return ExecuteReader(connection, CommandType.StoredProcedure, spName, commandParameters);
1251             }
1252             else 
1253             {
1254                 // Otherwise we can just call the SP without params
1255                                 // 否则只能调用无参数的SP
1256                 return ExecuteReader(connection, CommandType.StoredProcedure, spName);
1257             }
1258         }
1259 
1260         /// <summary>
1261         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. 
1262         /// 执行SQL命令(有一个返回值且不需要参数)以取代已有的SQL事务.
1263         /// </summary>
1264         /// <remarks>
1265         /// e.g.:  
1266         /// 例:
1267         ///  SqlDataReader dr = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders");
1268         /// </remarks>
1269         /// <param name="transaction">A valid SqlTransaction</param>
1270         /// <param name="transaction">一个合法的SQL事务</param>
1271         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1272         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1273         /// <param name="commandText">The stored procedure name or T-SQL command</param>
1274         /// <param name="commandText">存储过程名称或T-SQL命令</param>
1275         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
1276         /// <returns>返回一个包含由命令生成的结果集的SqlDataReader</returns>
1277         public static SqlDataReader ExecuteReader(SqlTransaction transaction, CommandType commandType, string commandText)
1278         {
1279             // Pass through the call providing null for the set of SqlParameters
1280             // 将给SqlParameters参数集赋空值的调用传递
1281             return ExecuteReader(transaction, commandType, commandText, (SqlParameter[])null);
1282         }
1283 
1284         /// <summary>
1285         /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction
1286         /// using the provided parameters.
1287         /// 利用提供的参数,执行SQL命令(返回一个结果集)以取代指定的SQL事务.
1288         /// </summary>
1289         /// <remarks>
1290         /// e.g.:  
1291         /// 例:
1292         ///   SqlDataReader dr = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
1293         /// </remarks>
1294         /// <param name="transaction">A valid SqlTransaction</param>
1295         /// <param name="transaction">一个合法的SQL事务</param>
1296         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1297         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1298         /// <param name="commandText">The stored procedure name or T-SQL command</param>
1299         /// <param name="commandText">存储过程名称或T-SQL命令</param>
1300         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
1301         /// <param name="commandParameters">一组用于执行命令的SqlParamters</param>
1302         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
1303         /// <returns>返回一个包含由命令生成的结果集的SqlDataReader</returns>
1304         public static SqlDataReader ExecuteReader(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
1305         {
1306             if( transaction == null ) throw new ArgumentNullException( "transaction" );
1307             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
1308 
1309             // Pass through to private overload, indicating that the connection is owned by the caller
1310                         // 传递给私有的过载(overload),表明此连接由调用者拥有
1311             return ExecuteReader(transaction.Connection, transaction, commandType, commandText, commandParameters, SqlConnectionOwnership.External);
1312         }
1313 
1314         /// <summary>
1315         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified
1316         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
1317         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
1318         /// 利用提供的参数值,通过SQL命令(返回一个结果集)执行存储过程以取代指定的SQL事务.
1319         /// 此方法查询数据库以发现用于存储过程参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
1320         /// </summary>
1321         /// <remarks>
1322         /// This method provides no access to output parameters or the stored procedure's return value parameter.
1323         /// 此方法不能获取输出参数或存储过程的返回值参数.
1324         /// 
1325         /// e.g.:  
1326         /// 例:
1327         ///  SqlDataReader dr = ExecuteReader(trans, "GetOrders", 24, 36);
1328         /// </remarks>
1329         /// <param name="transaction">A valid SqlTransaction</param>
1330         /// <param name="transaction">一个合法的SQL事务</param>
1331         /// <param name="spName">The name of the stored procedure</param>
1332         /// <param name="spName">存储过程名称</param>
1333         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
1334         /// <param name="parameterValues">分配为存储过程的输入值的对象集</param>
1335         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
1336         /// <returns>返回一个包含由命令生成的结果集的SqlDataReader</returns>
1337         public static SqlDataReader ExecuteReader(SqlTransaction transaction, string spName, params object[] parameterValues)
1338         {
1339             if( transaction == null ) throw new ArgumentNullException( "transaction" );
1340             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
1341             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
1342 
1343             // If we receive parameter values, we need to figure out where they go
1344             // 如果收到参数值,则需要指出它们的去向
1345             if ((parameterValues != null) && (parameterValues.Length > 0)) 
1346             {
1347                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
1348 
1349                 AssignParameterValues(commandParameters, parameterValues);
1350 
1351                 return ExecuteReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
1352             }
1353             else 
1354             {
1355                 // Otherwise we can just call the SP without params
1356                                 // 否则只能调用无参数的SP
1357                 return ExecuteReader(transaction, CommandType.StoredProcedure, spName);
1358             }
1359         }
1360 
1361         #endregion ExecuteReader
1362 
1363         #region ExecuteScalar
1364         
1365         /// <summary>
1366         /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the database specified in 
1367         /// the connection string. 
1368         /// 执行一个SQL命令(返回一个1x1的结果集且不需要参数)以取代在连接字符串中指定的数据库.
1369         /// </summary>
1370         /// <remarks>
1371         /// e.g.:  
1372         /// 例:
1373         ///  int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount");
1374         /// </remarks>
1375         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
1376         /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
1377         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1378         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1379         /// <param name="commandText">The stored procedure name or T-SQL command</param>
1380         /// <param name="commandText">存储过程名称或T-SQL命令</param>
1381         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
1382         /// <returns>返回一个对象,此对象包含由命令生成的1x1的结果集中的值</returns>
1383         public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText)
1384         {
1385             // Pass through the call providing null for the set of SqlParameters
1386             // 将给SqlParameters参数集赋空值的调用传递
1387             return ExecuteScalar(connectionString, commandType, commandText, (SqlParameter[])null);
1388         }
1389 
1390         /// <summary>
1391         /// Execute a SqlCommand (that returns a 1x1 resultset) against the database specified in the connection string 
1392         /// using the provided parameters.
1393         /// 利用给定的参数,执行一个SQL命令(返回一个1x1的结果集)以取代在连接字符串中指定的数据库.
1394         /// </summary>
1395         /// <remarks>
1396         /// e.g.:  
1397         /// 例:
1398         ///  int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));
1399         /// </remarks>
1400         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
1401         /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
1402         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1403         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1404         /// <param name="commandText">The stored procedure name or T-SQL command</param>
1405         /// <param name="commandText">存储过程名称或T-SQL命令</param>
1406         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
1407         /// <param name="commandParameters">一组用于执行命令的SqlParamters</param>
1408         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
1409         /// <returns>返回一个对象,此对象包含由命令生成的1x1的结果集中的值</returns>
1410         public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
1411         {
1412             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
1413             // Create & open a SqlConnection, and dispose of it after we are done
1414             // 创建并打开一个SQL连接,并在使用完后清除(dispose)
1415             using (SqlConnection connection = new SqlConnection(connectionString))
1416             {
1417                 connection.Open();
1418 
1419                 // Call the overload that takes a connection in place of the connection string
1420                 // 调用一个用于连接的过载(overload)来代替连接字符串
1421                 return ExecuteScalar(connection, commandType, commandText, commandParameters);
1422             }
1423         }
1424 
1425         /// <summary>
1426         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the database specified in 
1427         /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
1428         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
1429         /// 利用提供的参数值,通过SQL命令(返回一个1x1的结果集)执行存储过程以取代在连接字符串中指定的数据库.
1430         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
1431         /// </summary>
1432         /// <remarks>
1433         /// This method provides no access to output parameters or the stored procedure's return value parameter.
1434         /// 此方法不能获取输出参数或存储过程的返回值参数.
1435         /// 
1436         /// e.g.:  
1437         /// 例:
1438         ///  int orderCount = (int)ExecuteScalar(connString, "GetOrderCount", 24, 36);
1439         /// </remarks>
1440         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
1441         /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
1442         /// <param name="spName">The name of the stored procedure</param>
1443         /// <param name="spName">存储过程名称</param>
1444         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
1445         /// <param name="parameterValues">分配为存储过程的输入值的对象集</param>
1446         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
1447         /// <returns>返回一个对象,此对象包含由命令生成的1x1的结果集中的值</returns>
1448         public static object ExecuteScalar(string connectionString, string spName, params object[] parameterValues)
1449         {
1450             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
1451             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
1452             
1453             // If we receive parameter values, we need to figure out where they go
1454                         // 如果收到参数值,则需要指出它们的去向
1455             if ((parameterValues != null) && (parameterValues.Length > 0)) 
1456             {
1457                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
1458                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
1459                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
1460 
1461                 // Assign the provided values to these parameters based on parameter order
1462                 // 依据参数顺序给他们赋值
1463                 AssignParameterValues(commandParameters, parameterValues);
1464 
1465                 // Call the overload that takes an array of SqlParameters
1466                 // 调用获取SqlParameters参数集的过载
1467                 return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName, commandParameters);
1468             }
1469             else 
1470             {
1471                 // Otherwise we can just call the SP without params
1472                                 // 否则只能调用无参数的SP
1473                 return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName);
1474             }
1475         }
1476 
1477         /// <summary>
1478         /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the provided SqlConnection. 
1479         /// 执行一个SQL命令(返回一个1x1的结果集且不需要参数)以取代提供的SQL连接.
1480         /// </summary>
1481         /// <remarks>
1482         /// e.g.:  
1483         /// 例:
1484         ///  int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount");
1485         /// </remarks>
1486         /// <param name="connection">A valid SqlConnection</param>
1487         /// <param name="connection">一个合法的SQL连接</param>
1488         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1489         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1490         /// <param name="commandText">The stored procedure name or T-SQL command</param>
1491         /// <param name="commandText">存储过程名称或T-SQL命令</param>
1492         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
1493         /// <returns>返回一个对象,此对象包含由命令生成的1x1的结果集中的值</returns>
1494         public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText)
1495         {
1496             // Pass through the call providing null for the set of SqlParameters
1497             // 将给SqlParameters参数集赋空值的调用传递
1498             return ExecuteScalar(connection, commandType, commandText, (SqlParameter[])null);
1499         }
1500 
1501         /// <summary>
1502         /// Execute a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection 
1503         /// using the provided parameters.
1504         /// 利用提供的参数,执行一个SQL命令(返回一个1x1的结果集)以取代提供的SQL连接.
1505         /// </summary>
1506         /// <remarks>
1507         /// e.g.:  
1508         /// 例:
1509         ///  int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));
1510         /// </remarks>
1511         /// <param name="connection">A valid SqlConnection</param>
1512         /// <param name="connection">一个合法的SQL连接</param>
1513         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1514         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1515         /// <param name="commandText">The stored procedure name or T-SQL command</param>
1516         /// <param name="commandText">存储过程名称或T-SQL命令</param>
1517         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
1518         /// <param name="commandParameters">一组用于执行命令的SqlParamters</param>
1519         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
1520         /// <returns>返回一个对象,此对象包含由命令生成的1x1的结果集中的值</returns>
1521         public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
1522         {
1523             if( connection == null ) throw new ArgumentNullException( "connection" );
1524 
1525             // Create a command and prepare it for execution
1526                         // 创建一个用于执行的命令
1527             SqlCommand cmd = new SqlCommand();
1528 
1529             bool mustCloseConnection = false;
1530             PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection );
1531                 
1532             // Execute the command & return the results
1533                         // 执行命令,返回结果
1534             object retval = cmd.ExecuteScalar();
1535                 
1536             // Detach the SqlParameters from the command object, so they can be used again
1537                         // 从命令对象中分离(Detach)SqlParameters,以便它们能再次使用.
1538             cmd.Parameters.Clear();
1539 
1540             if( mustCloseConnection )
1541                 connection.Close();
1542 
1543             return retval;
1544         }
1545 
1546         /// <summary>
1547         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection 
1548         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
1549         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
1550         /// 利用提供的参数值,通过SQL命令(返回一个1x1的结果集)执行存储过程以取代制定的SQL连接.
1551         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
1552         /// </summary>
1553         /// <remarks>
1554         /// This method provides no access to output parameters or the stored procedure's return value parameter.
1555         /// 此方法不能获取输出参数或存储过程的返回值参数.
1556         /// 
1557         /// e.g.:  
1558         /// 例:
1559         ///  int orderCount = (int)ExecuteScalar(conn, "GetOrderCount", 24, 36);
1560         /// </remarks>
1561         /// <param name="connection">A valid SqlConnection</param>
1562         /// <param name="connection">一个合法的SQL连接</param>
1563         /// <param name="spName">The name of the stored procedure</param>
1564         /// <param name="spName">存储过程名称</param>
1565         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
1566         /// <param name="parameterValues">分配为存储过程的输入值的对象集</param>
1567         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
1568         /// <returns>返回一个对象,此对象包含由命令生成的1x1的结果集中的值</returns>
1569         public static object ExecuteScalar(SqlConnection connection, string spName, params object[] parameterValues)
1570         {
1571             if( connection == null ) throw new ArgumentNullException( "connection" );
1572             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
1573 
1574             // If we receive parameter values, we need to figure out where they go
1575             // 如果收到参数值,则需要指出它们的去向
1576             if ((parameterValues != null) && (parameterValues.Length > 0)) 
1577             {
1578                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
1579                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
1580                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
1581 
1582                 // Assign the provided values to these parameters based on parameter order
1583                 // 依据参数顺序给他们赋值
1584                 AssignParameterValues(commandParameters, parameterValues);
1585 
1586                 // Call the overload that takes an array of SqlParameters
1587                 // 调用获取SqlParameters参数集的过载
1588                 return ExecuteScalar(connection, CommandType.StoredProcedure, spName, commandParameters);
1589             }
1590             else 
1591             {
1592                 // Otherwise we can just call the SP without params
1593                                 // 否则只能调用无参数的SP
1594                 return ExecuteScalar(connection, CommandType.StoredProcedure, spName);
1595             }
1596         }
1597 
1598         /// <summary>
1599         /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the provided SqlTransaction. 
1600         /// 执行一个SQL命令(返回一个1x1的结果集且不需要参数)以取代提供的SQL事务.
1601         /// </summary>
1602         /// <remarks>
1603         /// e.g.:  
1604         /// 例:
1605         ///  int orderCount = (int)ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount");
1606         /// </remarks>
1607         /// <param name="transaction">A valid SqlTransaction</param>
1608         /// <param name="transaction">一个合法的SQL事务</param>
1609         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1610         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1611         /// <param name="commandText">The stored procedure name or T-SQL command</param>
1612         /// <param name="commandText">存储过程名称或T-SQL命令</param>
1613         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
1614         /// <returns>返回一个对象,此对象包含由命令生成的1x1的结果集中的值</returns>
1615         public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText)
1616         {
1617             // Pass through the call providing null for the set of SqlParameters
1618             // 将给SqlParameters参数集赋空值的调用传递
1619             return ExecuteScalar(transaction, commandType, commandText, (SqlParameter[])null);
1620         }
1621 
1622         /// <summary>
1623         /// Execute a SqlCommand (that returns a 1x1 resultset) against the specified SqlTransaction
1624         /// using the provided parameters.
1625         /// 利用提供的参数,执行一个SQL命令(返回一个1x1的结果集)以取代提供的SQL事务.
1626         /// </summary>
1627         /// <remarks>
1628         /// e.g.:  
1629         /// 例:
1630         ///  int orderCount = (int)ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));
1631         /// </remarks>
1632         /// <param name="transaction">A valid SqlTransaction</param>
1633         /// <param name="transaction">一个合法的SQL事务</param>
1634         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1635         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1636         /// <param name="commandText">The stored procedure name or T-SQL command</param>
1637         /// <param name="commandText">存储过程名称或T-SQL命令</param>
1638         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
1639         /// <param name="commandParameters">一组用于执行命令的SqlParamters</param>
1640         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
1641         /// <returns>返回一个对象,此对象包含由命令生成的1x1的结果集中的值</returns>
1642         public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
1643         {
1644             if( transaction == null ) throw new ArgumentNullException( "transaction" );
1645             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
1646 
1647             // Create a command and prepare it for execution
1648                         // 创建一个用于执行的命令
1649             SqlCommand cmd = new SqlCommand();
1650             bool mustCloseConnection = false;
1651             PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection );
1652                 
1653             // Execute the command & return the results
1654                         // 执行命令,返回结果
1655             object retval = cmd.ExecuteScalar();
1656                 
1657             // Detach the SqlParameters from the command object, so they can be used again
1658                         // 从命令对象中分离(Detach)SqlParameters,以便它们能再次使用.
1659             cmd.Parameters.Clear();
1660             return retval;
1661         }
1662 
1663         /// <summary>
1664         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified
1665         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
1666         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
1667         /// 利用提供的参数值,通过SQL命令(返回一个1x1的结果集)执行存储过程以取代指定的SQL事务.
1668         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
1669         /// </summary>
1670         /// <remarks>
1671         /// This method provides no access to output parameters or the stored procedure's return value parameter.
1672         /// 此方法不能获取输出参数或存储过程的返回值参数.
1673         /// 
1674         /// e.g.:  
1675         /// 例:
1676         ///  int orderCount = (int)ExecuteScalar(trans, "GetOrderCount", 24, 36);
1677         /// </remarks>
1678         /// <param name="transaction">A valid SqlTransaction</param>
1679         /// <param name="transaction">一个合法的SQL事务</param>
1680         /// <param name="spName">The name of the stored procedure</param>
1681         /// <param name="spName">存储过程名称</param>
1682         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
1683         /// <param name="parameterValues">分配为存储过程的输入值的对象集</param>
1684         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
1685         /// <returns>返回一个对象,此对象包含由命令生成的1x1的结果集中的值</returns>
1686         public static object ExecuteScalar(SqlTransaction transaction, string spName, params object[] parameterValues)
1687         {
1688             if( transaction == null ) throw new ArgumentNullException( "transaction" );
1689             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
1690             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
1691 
1692             // If we receive parameter values, we need to figure out where they go
1693             // 如果收到参数值,则需要指出它们的去向
1694             if ((parameterValues != null) && (parameterValues.Length > 0)) 
1695             {
1696                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
1697                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
1698                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
1699 
1700                 // Assign the provided values to these parameters based on parameter order
1701                 // 依据参数顺序给他们赋值
1702                 AssignParameterValues(commandParameters, parameterValues);
1703 
1704                 // Call the overload that takes an array of SqlParameters
1705                 // 调用获取SqlParameters参数集的过载
1706                 return ExecuteScalar(transaction, CommandType.StoredProcedure, spName, commandParameters);
1707             }
1708             else 
1709             {
1710                 // Otherwise we can just call the SP without params
1711                                 // 否则只能调用无参数的SP
1712                 return ExecuteScalar(transaction, CommandType.StoredProcedure, spName);
1713             }
1714         }
1715 
1716         #endregion ExecuteScalar    
1717 
1718         #region ExecuteXmlReader
1719         /// <summary>
1720         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. 
1721         /// 执行一个SQL命令(返回一个1x1的结果集且不需要参数)以取代提供的SQL连接.
1722         /// </summary>
1723         /// <remarks>
1724         /// e.g.:  
1725         /// 例:
1726         ///  XmlReader r = ExecuteXmlReader(conn, CommandType.StoredProcedure, "GetOrders");
1727         /// </remarks>
1728         /// <param name="connection">A valid SqlConnection</param>
1729         /// <param name="connection">一个合法的SQL连接</param>
1730         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1731         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1732         /// <param name="commandText">The stored procedure name or T-SQL command using "FOR XML AUTO"</param>
1733         /// <param name="commandText">存储过程名称或使用"FOR XML AUTO"的T-SQL命令</param>
1734         /// <returns>An XmlReader containing the resultset generated by the command</returns>
1735         /// <returns>包含有命令生成的结果集的XmlReader</returns>
1736         public static XmlReader ExecuteXmlReader(SqlConnection connection, CommandType commandType, string commandText)
1737         {
1738             // Pass through the call providing null for the set of SqlParameters
1739             // 将给SqlParameters参数集赋空值的调用传递
1740             return ExecuteXmlReader(connection, commandType, commandText, (SqlParameter[])null);
1741         }
1742 
1743         /// <summary>
1744         /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 
1745         /// using the provided parameters.
1746         /// 利用提供的参数,执行一个SQL命令(返回一个结果集)以取代提供的SQL连接.
1747         /// </summary>
1748         /// <remarks>
1749         /// e.g.:  
1750         /// 例:
1751         ///  XmlReader r = ExecuteXmlReader(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
1752         /// </remarks>
1753         /// <param name="connection">A valid SqlConnection</param>
1754         /// <param name="connection">一个合法的SQL连接</param>
1755         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1756         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1757         /// <param name="commandText">The stored procedure name or T-SQL command using "FOR XML AUTO"</param>
1758         /// <param name="commandText">存储过程名称或使用"FOR XML AUTO"的T-SQL命令</param>
1759         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
1760         /// <param name="commandParameters">一组用于执行命令的SqlParamters</param>
1761         /// <returns>An XmlReader containing the resultset generated by the command</returns>
1762         /// <returns>包含有命令生成的结果集的XmlReader</returns>
1763         public static XmlReader ExecuteXmlReader(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
1764         {
1765             if( connection == null ) throw new ArgumentNullException( "connection" );
1766 
1767             bool mustCloseConnection = false;
1768             // Create a command and prepare it for execution
1769                         // 创建一个用于执行的命令
1770             SqlCommand cmd = new SqlCommand();
1771             try
1772             {
1773                 PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection );
1774             
1775                 // Create the DataAdapter & DataSet
1776                                 // 创建DataAdapter和DataSet
1777                 XmlReader retval = cmd.ExecuteXmlReader();
1778             
1779                 // Detach the SqlParameters from the command object, so they can be used again
1780                                 // 从命令对象中分离(Detach)SqlParameters,以便它们能再次使用.
1781                 cmd.Parameters.Clear();
1782 
1783                 return retval;
1784             }
1785             catch
1786             {    
1787                 if( mustCloseConnection )
1788                     connection.Close();
1789                 throw;
1790             }
1791         }
1792 
1793         /// <summary>
1794         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
1795         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
1796         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
1797         /// 利用提供的参数值,通过SQL命令(返回一个结果集)执行存储过程以取代指定的SQL连接.
1798         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
1799         /// </summary>
1800         /// <remarks>
1801         /// This method provides no access to output parameters or the stored procedure's return value parameter.
1802         /// 此方法不能获取输出参数或存储过程的返回值参数.
1803         /// 
1804         /// e.g.:  
1805         /// 例:
1806         ///  XmlReader r = ExecuteXmlReader(conn, "GetOrders", 24, 36);
1807         /// </remarks>
1808         /// <param name="connection">A valid SqlConnection</param>
1809         /// <param name="connection">一个合法的SQL连接</param>
1810         /// <param name="spName">The name of the stored procedure using "FOR XML AUTO"</param>
1811         /// <param name="spName">用了"FOR XML AUTO"的存储过程的名称</param>
1812         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
1813         /// <param name="parameterValues">分配为存储过程的输入值的对象集</param>
1814         /// <returns>An XmlReader containing the resultset generated by the command</returns>
1815         /// <returns>包含有命令生成的结果集的XmlReader</returns>
1816         public static XmlReader ExecuteXmlReader(SqlConnection connection, string spName, params object[] parameterValues)
1817         {
1818             if( connection == null ) throw new ArgumentNullException( "connection" );
1819             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
1820 
1821             // If we receive parameter values, we need to figure out where they go
1822             // 如果收到参数值,则需要指出它们的去向
1823             if ((parameterValues != null) && (parameterValues.Length > 0)) 
1824             {
1825                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
1826                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
1827                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
1828 
1829                 // Assign the provided values to these parameters based on parameter order
1830                 // 依据参数顺序给他们赋值
1831                 AssignParameterValues(commandParameters, parameterValues);
1832 
1833                 // Call the overload that takes an array of SqlParameters
1834                 // 调用获取SqlParameters参数集的过载
1835                 return ExecuteXmlReader(connection, CommandType.StoredProcedure, spName, commandParameters);
1836             }
1837             else 
1838             {
1839                 // Otherwise we can just call the SP without params
1840                                 // 否则只能调用无参数的SP
1841                 return ExecuteXmlReader(connection, CommandType.StoredProcedure, spName);
1842             }
1843         }
1844 
1845         /// <summary>
1846         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. 
1847         /// 执行一个SQL命令(返回一个结果集且不需要参数)以取代提供的SQL事务.
1848         /// </summary>
1849         /// <remarks>
1850         /// e.g.:  
1851         /// 例:
1852         ///  XmlReader r = ExecuteXmlReader(trans, CommandType.StoredProcedure, "GetOrders");
1853         /// </remarks>
1854         /// <param name="transaction">A valid SqlTransaction</param>
1855         /// <param name="transaction">一个合法的SQL事务</param>
1856         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1857         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1858         /// <param name="commandText">The stored procedure name or T-SQL command using "FOR XML AUTO"</param>
1859         /// <param name="commandText">存储过程名称或使用"FOR XML AUTO"的T-SQL命令</param>
1860         /// <returns>An XmlReader containing the resultset generated by the command</returns>
1861         /// <returns>包含有命令生成的结果集的XmlReader</returns>
1862         public static XmlReader ExecuteXmlReader(SqlTransaction transaction, CommandType commandType, string commandText)
1863         {
1864             // Pass through the call providing null for the set of SqlParameters
1865             // 将给SqlParameters参数集赋空值的调用传递
1866             return ExecuteXmlReader(transaction, commandType, commandText, (SqlParameter[])null);
1867         }
1868 
1869         /// <summary>
1870         /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction
1871         /// using the provided parameters.
1872         /// 利用提供的参数,执行一个SQL命令(返回一个结果集)以取代提供的SQL事务.
1873         /// </summary>
1874         /// <remarks>
1875         /// e.g.:  
1876         /// 例:
1877         ///  XmlReader r = ExecuteXmlReader(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
1878         /// </remarks>
1879         /// <param name="transaction">A valid SqlTransaction</param>
1880         /// <param name="transaction">一个合法的SQL事务</param>
1881         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1882         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1883         /// <param name="commandText">The stored procedure name or T-SQL command using "FOR XML AUTO"</param>
1884         /// <param name="commandText">存储过程名称或使用"FOR XML AUTO"的T-SQL命令</param>
1885         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
1886         /// <param name="commandParameters">一组用于执行命令的SqlParamters</param>
1887         /// <returns>An XmlReader containing the resultset generated by the command</returns>
1888         /// <returns>包含有命令生成的结果集的XmlReader</returns>
1889         public static XmlReader ExecuteXmlReader(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
1890         {
1891             if( transaction == null ) throw new ArgumentNullException( "transaction" );
1892             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
1893 
1894             // Create a command and prepare it for execution
1895                         // 创建一个用于执行的命令
1896             SqlCommand cmd = new SqlCommand();
1897             bool mustCloseConnection = false;
1898             PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection );
1899             
1900             // Create the DataAdapter & DataSet
1901                         // 创建DataAdapter和DataSet
1902             XmlReader retval = cmd.ExecuteXmlReader();
1903             
1904             // Detach the SqlParameters from the command object, so they can be used again
1905                         // 从命令对象中分离(Detach)SqlParameters,以便它们能再次使用.
1906             cmd.Parameters.Clear();
1907             return retval;            
1908         }
1909 
1910         /// <summary>
1911         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified 
1912         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
1913         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
1914         /// 利用提供的参数值,通过SQL命令(返回一个结果集)执行存储过程以取代指定的SQL事务.
1915         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
1916         /// </summary>
1917         /// <remarks>
1918         /// This method provides no access to output parameters or the stored procedure's return value parameter.
1919         /// 此方法不能获取输出参数或存储过程的返回值参数.
1920         /// 
1921         /// e.g.:  
1922         /// 例:
1923         ///  XmlReader r = ExecuteXmlReader(trans, "GetOrders", 24, 36);
1924         /// </remarks>
1925         /// <param name="transaction">A valid SqlTransaction</param>
1926         /// <param name="transaction">一个合法的SQL事务</param>
1927         /// <param name="spName">The name of the stored procedure</param>
1928         /// <param name="spName">存储过程名称</param>
1929         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
1930         /// <param name="parameterValues">分配为存储过程的输入值的对象集</param>
1931         /// <returns>A dataset containing the resultset generated by the command</returns>
1932         /// <returns>返回一个包含由命令生成的结果集的数据集(dataset)</returns>
1933         public static XmlReader ExecuteXmlReader(SqlTransaction transaction, string spName, params object[] parameterValues)
1934         {
1935             if( transaction == null ) throw new ArgumentNullException( "transaction" );
1936             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
1937             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
1938 
1939             // If we receive parameter values, we need to figure out where they go
1940             // 如果收到参数值,则需要指出它们的去向
1941             if ((parameterValues != null) && (parameterValues.Length > 0)) 
1942             {
1943                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
1944                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
1945                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
1946 
1947                 // Assign the provided values to these parameters based on parameter order
1948                 // 依据参数顺序给他们赋值
1949                 AssignParameterValues(commandParameters, parameterValues);
1950 
1951                 // Call the overload that takes an array of SqlParameters
1952                 // 调用获取SqlParameters参数集的过载
1953                 return ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
1954             }
1955             else 
1956             {
1957                 // Otherwise we can just call the SP without params
1958                                 // 否则只能调用无参数的SP
1959                 return ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName);
1960             }
1961         }
1962 
1963         #endregion ExecuteXmlReader
1964 
1965         #region FillDataset
1966         /// <summary>
1967         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in 
1968         /// the connection string. 
1969         /// 利用提供的参数,执行一个SQL命令(返回一个结果集且不需要参数)以取代由连接字符串指定的数据库.
1970         /// </summary>
1971         /// <remarks>
1972         /// e.g.:  
1973         /// 例:
1974         ///  FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"});
1975         /// </remarks>
1976         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
1977         /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
1978         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
1979         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
1980         /// <param name="commandText">The stored procedure name or T-SQL command</param>
1981         /// <param name="commandText">存储过程名称或T-SQL命令</param>
1982         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
1983         /// <param name="dataSet">用于包含由命令生成的结果集的数据集(dataset)</param>
1984         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
1985         /// by a user defined name (probably the actual table name)</param>
1986         /// <param name="tableNames">此集合用于创建表映射,从而允许数据表(DataTables)被用户参照来定义名称(可能是真实的表名)</param>
1987 
1988         public static void FillDataset(string connectionString, CommandType commandType, string commandText, DataSet dataSet, string[] tableNames)
1989         {
1990             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
1991             if( dataSet == null ) throw new ArgumentNullException( "dataSet" );
1992             
1993             // Create & open a SqlConnection, and dispose of it after we are done
1994                         // 创建并打开一个SQL连接,并在使用完后清除(dispose)
1995             using (SqlConnection connection = new SqlConnection(connectionString))
1996             {
1997                 connection.Open();
1998 
1999                 // Call the overload that takes a connection in place of the connection string
2000                 // 调用一个用于连接的过载(overload)来代替连接字符串
2001                 FillDataset(connection, commandType, commandText, dataSet, tableNames);
2002             }
2003         }
2004 
2005         /// <summary>
2006         /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string 
2007         /// using the provided parameters.
2008         /// 利用提供的参数,执行一个SQL命令(返回一个结果集)以取代由连接字符串指定的数据库.
2009         /// </summary>
2010         /// <remarks>
2011         /// e.g.:  
2012         /// 例:
2013         ///  FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24));
2014         /// </remarks>
2015         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
2016         /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
2017         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
2018         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
2019         /// <param name="commandText">The stored procedure name or T-SQL command</param>
2020         /// <param name="commandText">存储过程名称或T-SQL命令</param>
2021         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
2022         /// <param name="commandParameters">一组用于执行命令的SqlParamters</param>
2023         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
2024         /// <param name="dataSet">用于包含由命令生成的结果集的数据集(dataset)</param>
2025         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
2026         /// by a user defined name (probably the actual table name)</param>
2027         /// <param name="tableNames">此集合用于创建表映射,从而允许数据表(DataTables)被用户参照来定义名称(可能是真实的表名)</param>
2028         public static void FillDataset(string connectionString, CommandType commandType,
2029             string commandText, DataSet dataSet, string[] tableNames,
2030             params SqlParameter[] commandParameters)
2031         {
2032             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
2033             if( dataSet == null ) throw new ArgumentNullException( "dataSet" );
2034             // Create & open a SqlConnection, and dispose of it after we are done
2035             // 创建并打开一个SQL连接,并在使用完后清除(dispose)
2036             using (SqlConnection connection = new SqlConnection(connectionString))
2037             {
2038                 connection.Open();
2039 
2040                 // Call the overload that takes a connection in place of the connection string
2041                 // 调用一个用于连接的过载(overload)来代替连接字符串
2042                 FillDataset(connection, commandType, commandText, dataSet, tableNames, commandParameters);
2043             }
2044         }
2045 
2046         /// <summary>
2047         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 
2048         /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
2049         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
2050         /// 利用提供的参数值,通过SQL命令(返回一个结果集)执行存储过程以取代在连接字符串中指定的数据库.
2051         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2052         /// </summary>
2053         /// <remarks>
2054         /// This method provides no access to output parameters or the stored procedure's return value parameter.
2055         /// 此方法不能获取输出参数或存储过程的返回值参数.
2056         /// 
2057         /// e.g.:  
2058         /// 例:
2059         ///  FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, 24);
2060         /// </remarks>
2061         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
2062         /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
2063         /// <param name="spName">The name of the stored procedure</param>
2064         /// <param name="spName">存储过程名称</param>
2065         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
2066         /// <param name="dataSet">用于包含由命令生成的结果集的数据集(dataset)</param>
2067         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
2068         /// by a user defined name (probably the actual table name)
2069         /// </param>    
2070         /// <param name="tableNames">此集合用于创建表映射,从而允许数据表(DataTables)被用户参照来定义名称(可能是真实的表名)</param>
2071         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
2072         /// <param name="parameterValues">分配为存储过程的输入值的对象集</param>
2073         public static void FillDataset(string connectionString, string spName,
2074             DataSet dataSet, string[] tableNames,
2075             params object[] parameterValues)
2076         {
2077             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
2078             if( dataSet == null ) throw new ArgumentNullException( "dataSet" );
2079             // Create & open a SqlConnection, and dispose of it after we are done
2080             // 创建并打开一个SQL连接,并在使用完后清除(dispose)
2081             using (SqlConnection connection = new SqlConnection(connectionString))
2082             {
2083                 connection.Open();
2084 
2085                 // Call the overload that takes a connection in place of the connection string
2086                 // 调用一个用于连接的过载(overload)来代替连接字符串
2087                 FillDataset (connection, spName, dataSet, tableNames, parameterValues);
2088             }
2089         }
2090 
2091         /// <summary>
2092         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. 
2093         /// 执行一个SQL命令(返回一个结果集且不需要参数)以取代提供的SQL连接.
2094         /// </summary>
2095         /// <remarks>
2096         /// e.g.:  
2097         /// 例:
2098         ///  FillDataset(conn, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"});
2099         /// </remarks>
2100         /// <param name="connection">A valid SqlConnection</param>
2101         /// <param name="connection">一个合法的SQL连接</param>
2102         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
2103         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
2104         /// <param name="commandText">The stored procedure name or T-SQL command</param>
2105         /// <param name="commandText">存储过程名称或T-SQL命令</param>
2106         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
2107         /// <param name="dataSet">用于包含由命令生成的结果集的数据集(dataset)</param>
2108         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
2109         /// by a user defined name (probably the actual table name)
2110         /// </param>    
2111         /// <param name="tableNames">此集合用于创建表映射,从而允许数据表(DataTables)被用户参照来定义名称(可能是真实的表名)</param>
2112         public static void FillDataset(SqlConnection connection, CommandType commandType, 
2113             string commandText, DataSet dataSet, string[] tableNames)
2114         {
2115             FillDataset(connection, commandType, commandText, dataSet, tableNames, null);
2116         }
2117 
2118         /// <summary>
2119         /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 
2120         /// using the provided parameters.
2121         /// 利用提供的参数,执行一个SQL命令(返回一个结果集)以取代提供的SQL连接.
2122         /// </summary>
2123         /// <remarks>
2124         /// e.g.:  
2125         /// 例:
2126         ///  FillDataset(conn, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24));
2127         /// </remarks>
2128         /// <param name="connection">A valid SqlConnection</param>
2129         /// <param name="connection">一个合法的SQL连接</param>
2130         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
2131         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
2132         /// <param name="commandText">The stored procedure name or T-SQL command</param>
2133         /// <param name="commandText">存储过程名称或T-SQL命令</param>
2134         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
2135         /// <param name="dataSet">用于包含由命令生成的结果集的数据集(dataset)</param>
2136         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
2137         /// by a user defined name (probably the actual table name)
2138         /// </param>
2139         /// <param name="tableNames">此集合用于创建表映射,从而允许数据表(DataTables)被用户参照来定义名称(可能是真实的表名)</param>
2140         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
2141         /// <param name="commandParameters">一组用于执行命令的SqlParamters</param>
2142         public static void FillDataset(SqlConnection connection, CommandType commandType, 
2143             string commandText, DataSet dataSet, string[] tableNames,
2144             params SqlParameter[] commandParameters)
2145         {
2146             FillDataset(connection, null, commandType, commandText, dataSet, tableNames, commandParameters);
2147         }
2148 
2149         /// <summary>
2150         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
2151         /// using the provided parameter values.  This method will query the database to discover the parameters for the 
2152         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
2153         /// 利用提供的参数值,通过SQL命令(返回一个结果集)执行存储过程以取代指定的SQL连接.
2154         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2155         /// </summary>
2156         /// <remarks>
2157         /// This method provides no access to output parameters or the stored procedure's return value parameter.
2158         /// 此方法不能获取输出参数或存储过程的返回值参数.
2159         /// 
2160         /// e.g.:  
2161         /// 例:
2162         ///  FillDataset(conn, "GetOrders", ds, new string[] {"orders"}, 24, 36);
2163         /// </remarks>
2164         /// <param name="connection">A valid SqlConnection</param>
2165         /// <param name="connection">一个合法的SQL连接</param>
2166         /// <param name="spName">The name of the stored procedure</param>
2167         /// <param name="spName">存储过程名称</param>
2168         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
2169         /// <param name="dataSet">用于包含由命令生成的结果集的数据集(dataset)</param>
2170         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
2171         /// by a user defined name (probably the actual table name)
2172         /// </param>
2173         /// <param name="tableNames">此集合用于创建表映射,从而允许数据表(DataTables)被用户参照来定义名称(可能是真实的表名)</param>
2174         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
2175         /// <param name="parameterValues">分配为存储过程的输入值的对象集</param>
2176         public static void FillDataset(SqlConnection connection, string spName, 
2177             DataSet dataSet, string[] tableNames,
2178             params object[] parameterValues)
2179         {
2180             if ( connection == null ) throw new ArgumentNullException( "connection" );
2181             if (dataSet == null ) throw new ArgumentNullException( "dataSet" );
2182             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2183 
2184             // If we receive parameter values, we need to figure out where they go
2185                         // 如果收到参数值,则需要指出它们的去向
2186             if ((parameterValues != null) && (parameterValues.Length > 0)) 
2187             {
2188                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2189                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2190                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
2191 
2192                 // Assign the provided values to these parameters based on parameter order
2193                 // 依据参数顺序给他们赋值
2194                 AssignParameterValues(commandParameters, parameterValues);
2195 
2196                 // Call the overload that takes an array of SqlParameters
2197                 // 调用获取SqlParameters参数集的过载
2198                 FillDataset(connection, CommandType.StoredProcedure, spName, dataSet, tableNames, commandParameters);
2199             }
2200             else 
2201             {
2202                 // Otherwise we can just call the SP without params
2203                                 // 否则只能调用无参数的SP
2204                 FillDataset(connection, CommandType.StoredProcedure, spName, dataSet, tableNames);
2205             }    
2206         }
2207 
2208         /// <summary>
2209         /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. 
2210         /// 执行一个SQL命令(返回一个结果集且不需要参数)以取代提供的SQL事务.
2211         /// </summary>
2212         /// <remarks>
2213         /// e.g.:  
2214         /// 例:
2215         ///  FillDataset(trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"});
2216         /// </remarks>
2217         /// <param name="transaction">A valid SqlTransaction</param>
2218         /// <param name="transaction">一个合法的SQL事务</param>
2219         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
2220         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
2221         /// <param name="commandText">The stored procedure name or T-SQL command</param>
2222         /// <param name="commandText">存储过程名称或T-SQL命令</param>
2223         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
2224         /// <param name="dataSet">用于包含由命令生成的结果集的数据集(dataset)</param>
2225         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
2226         /// by a user defined name (probably the actual table name)
2227         /// </param>
2228         /// <param name="tableNames">此集合用于创建表映射,从而允许数据表(DataTables)被用户参照来定义名称(可能是真实的表名)</param>
2229         public static void FillDataset(SqlTransaction transaction, CommandType commandType, 
2230             string commandText,
2231             DataSet dataSet, string[] tableNames)
2232         {
2233             FillDataset (transaction, commandType, commandText, dataSet, tableNames, null);    
2234         }
2235 
2236         /// <summary>
2237         /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction
2238         /// using the provided parameters.
2239         /// 利用提供的参数,执行一个SQL命令(返回一个结果集)以取代提供的SQL事务.
2240         /// </summary>
2241         /// <remarks>
2242         /// e.g.:  
2243         /// 例:
2244         ///  FillDataset(trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24));
2245         /// </remarks>
2246         /// <param name="transaction">A valid SqlTransaction</param>
2247         /// <param name="transaction">一个合法的SQL事务</param>
2248         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
2249         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
2250         /// <param name="commandText">The stored procedure name or T-SQL command</param>
2251         /// <param name="commandText">存储过程名称或T-SQL命令</param>
2252         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
2253         /// <param name="dataSet">用于包含由命令生成的结果集的数据集(dataset)</param>
2254         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
2255         /// by a user defined name (probably the actual table name)
2256         /// </param>
2257         /// <param name="tableNames">此集合用于创建表映射,从而允许数据表(DataTables)被用户参照来定义名称(可能是真实的表名)</param>
2258         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
2259         /// <param name="commandParameters">一组用于执行命令的SqlParamters</param>
2260         public static void FillDataset(SqlTransaction transaction, CommandType commandType, 
2261             string commandText, DataSet dataSet, string[] tableNames,
2262             params SqlParameter[] commandParameters)
2263         {
2264             FillDataset(transaction.Connection, transaction, commandType, commandText, dataSet, tableNames, commandParameters);
2265         }
2266 
2267         /// <summary>
2268         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified 
2269         /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
2270         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
2271         /// 利用提供的参数值,通过SQL命令(返回一个结果集)执行存储过程以取代指定的SQL事务.
2272         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2273         /// </summary>
2274         /// <remarks>
2275         /// This method provides no access to output parameters or the stored procedure's return value parameter.
2276         /// 此方法不能获取输出参数或存储过程的返回值参数.
2277         /// 
2278         /// e.g.:  
2279         /// 例:
2280         ///  FillDataset(trans, "GetOrders", ds, new string[]{"orders"}, 24, 36);
2281         /// </remarks>
2282         /// <param name="transaction">A valid SqlTransaction</param>
2283         /// <param name="transaction">一个合法的SQL事务</param>
2284         /// <param name="spName">The name of the stored procedure</param>
2285         /// <param name="spName">存储过程名称</param>
2286         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
2287         /// <param name="dataSet">用于包含由命令生成的结果集的数据集(dataset)</param>
2288         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
2289         /// by a user defined name (probably the actual table name)
2290         /// </param>
2291         /// <param name="tableNames">此集合用于创建表映射,从而允许数据表(DataTables)被用户参照来定义名称(可能是真实的表名)</param>
2292         /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
2293         /// <param name="parameterValues">分配为存储过程的输入值的对象集</param>
2294         public static void FillDataset(SqlTransaction transaction, string spName,
2295             DataSet dataSet, string[] tableNames,
2296             params object[] parameterValues) 
2297         {
2298             if( transaction == null ) throw new ArgumentNullException( "transaction" );
2299             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
2300             if( dataSet == null ) throw new ArgumentNullException( "dataSet" );
2301             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2302 
2303             // If we receive parameter values, we need to figure out where they go
2304             // 如果收到参数值,则需要指出它们的去向
2305             if ((parameterValues != null) && (parameterValues.Length > 0)) 
2306             {
2307                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2308                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2309                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
2310 
2311                 // Assign the provided values to these parameters based on parameter order
2312                 // 依据参数顺序给他们赋值
2313                 AssignParameterValues(commandParameters, parameterValues);
2314 
2315                 // Call the overload that takes an array of SqlParameters
2316                 // 调用获取SqlParameters参数集的过载
2317                 FillDataset(transaction, CommandType.StoredProcedure, spName, dataSet, tableNames, commandParameters);
2318             }
2319             else 
2320             {
2321                 // Otherwise we can just call the SP without params
2322                                 // 否则只能调用无参数的SP
2323                 FillDataset(transaction, CommandType.StoredProcedure, spName, dataSet, tableNames);
2324             }    
2325         }
2326 
2327         /// <summary>
2328         /// Private helper method that execute a SqlCommand (that returns a resultset) against the specified SqlTransaction and SqlConnection
2329         /// using the provided parameters.
2330         /// </summary>
2331         /// <remarks>
2332         /// e.g.:  
2333         /// 例:
2334         ///  FillDataset(conn, trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24));
2335         /// </remarks>
2336         /// <param name="connection">A valid SqlConnection</param>
2337         /// <param name="connection">一个合法的SQL连接</param>
2338         /// <param name="transaction">A valid SqlTransaction</param>
2339         /// <param name="transaction">一个合法的SQL事务</param>
2340         /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
2341         /// <param name="commandType">命令类型(存储过程、文本及其他)</param>
2342         /// <param name="commandText">The stored procedure name or T-SQL command</param>
2343         /// <param name="commandText">存储过程名称或T-SQL命令</param>
2344         /// <param name="dataSet">A dataset wich will contain the resultset generated by the command</param>
2345         /// <param name="dataSet">用于包含由命令生成的结果集的数据集(dataset)</param>
2346         /// <param name="tableNames">This array will be used to create table mappings allowing the DataTables to be referenced
2347         /// by a user defined name (probably the actual table name)
2348         /// </param>
2349         /// <param name="tableNames">此集合用于创建表映射,从而允许数据表(DataTables)被用户参照来定义名称(可能是真实的表名)</param>
2350         /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
2351         /// <param name="commandParameters">一组用于执行命令的SqlParamters</param>
2352         private static void FillDataset(SqlConnection connection, SqlTransaction transaction, CommandType commandType, 
2353             string commandText, DataSet dataSet, string[] tableNames,
2354             params SqlParameter[] commandParameters)
2355         {
2356             if( connection == null ) throw new ArgumentNullException( "connection" );
2357             if( dataSet == null ) throw new ArgumentNullException( "dataSet" );
2358 
2359             // Create a command and prepare it for execution
2360                         // 创建一个用于执行的命令
2361             SqlCommand command = new SqlCommand();
2362             bool mustCloseConnection = false;
2363             PrepareCommand(command, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection );
2364                 
2365             // Create the DataAdapter & DataSet
2366                         // 创建DataAdapter和DataSet
2367             using( SqlDataAdapter dataAdapter = new SqlDataAdapter(command) )
2368             {
2369                 
2370                 // Add the table mappings specified by the user
2371                                 // 添加由用户制定的表映射
2372                 if (tableNames != null && tableNames.Length > 0)
2373                 {
2374                     string tableName = "Table";
2375                     for (int index=0; index < tableNames.Length; index++)
2376                     {
2377                         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" );
2378                         dataAdapter.TableMappings.Add(tableName, tableNames[index]);
2379                         tableName += (index + 1).ToString();
2380                     }
2381                 }
2382                 
2383                 // Fill the DataSet using default values for DataTable names, etc
2384                                 // 用为数据表(DataTable)名等提供的默认值填充DataSet
2385                 dataAdapter.Fill(dataSet);
2386 
2387                 // Detach the SqlParameters from the command object, so they can be used again
2388                                 // 从命令对象中分离(Detach)SqlParameters,以便它们能再次使用.
2389                 command.Parameters.Clear();
2390             }
2391 
2392             if( mustCloseConnection )
2393                 connection.Close();
2394         }
2395         #endregion
2396         
2397         #region UpdateDataset
2398         /// <summary>
2399         /// Executes the respective command for each inserted, updated, or deleted row in the DataSet.
2400         /// 为在数据集(DataSet)中插入、更新、删除列执行相应的命令
2401         /// </summary>
2402         /// <remarks>
2403         /// e.g.:  
2404         /// 例:
2405         ///  UpdateDataset(conn, insertCommand, deleteCommand, updateCommand, dataSet, "Order");
2406         /// </remarks>
2407         /// <param name="insertCommand">A valid transact-SQL statement or stored procedure to insert new records into the data source</param>
2408         /// <param name="insertCommand">合法的transact-SQL声明或向数据源中插入新纪录的存储过程</param>
2409         /// <param name="deleteCommand">A valid transact-SQL statement or stored procedure to delete records from the data source</param>
2410         /// <param name="deleteCommand">合法的transact-SQL声明或从数据源中删除纪录的存储过程</param>
2411         /// <param name="updateCommand">A valid transact-SQL statement or stored procedure used to update records in the data source</param>
2412         /// <param name="updateCommand">合法的transact-SQL声明或更新数据源中纪录的存储过程</param>
2413         /// <param name="dataSet">The DataSet used to update the data source</param>
2414         /// <param name="dataSet">用于更新数据源的数据集(DataSet)</param>
2415         /// <param name="tableName">The DataTable used to update the data source.</param>
2416         /// <param name="tableName">用于更新数据源的数据表(DataTable).</param>
2417         public static void UpdateDataset(SqlCommand insertCommand, SqlCommand deleteCommand, SqlCommand updateCommand, DataSet dataSet, string tableName)
2418         {
2419             if( insertCommand == null ) throw new ArgumentNullException( "insertCommand" );
2420             if( deleteCommand == null ) throw new ArgumentNullException( "deleteCommand" );
2421             if( updateCommand == null ) throw new ArgumentNullException( "updateCommand" );
2422             if( tableName == null || tableName.Length == 0 ) throw new ArgumentNullException( "tableName" ); 
2423 
2424             // Create a SqlDataAdapter, and dispose of it after we are done
2425             // 创建一个SqlDataAdapter,使用过后将其清除(dispose)
2426             using (SqlDataAdapter dataAdapter = new SqlDataAdapter())
2427             {
2428                 // Set the data adapter commands
2429                 // 设定dataAdapter命令
2430                 dataAdapter.UpdateCommand = updateCommand;
2431                 dataAdapter.InsertCommand = insertCommand;
2432                 dataAdapter.DeleteCommand = deleteCommand;
2433 
2434                 // Update the dataset changes in the data source
2435                 // 根据数据源中的改变更新数据集(dataset)
2436                 dataAdapter.Update (dataSet, tableName); 
2437 
2438                 // Commit all the changes made to the DataSet
2439                 // 提交所有对数据集的改变
2440                 dataSet.AcceptChanges();
2441             }
2442         }
2443         #endregion
2444 
2445         #region CreateCommand
2446         /// <summary>
2447         /// Simplify the creation of a Sql command object by allowing
2448         /// a stored procedure and optional parameters to be provided
2449         /// 通过允许提供存储过程和可选参数来简化命令对象的创建
2450         /// </summary>
2451         /// <remarks>
2452         /// e.g.:  
2453         /// 例:
2454         ///  SqlCommand command = CreateCommand(conn, "AddCustomer", "CustomerID", "CustomerName");
2455         /// </remarks>
2456         /// <param name="connection">A valid SqlConnection object</param>
2457         /// <param name="connection">合法的SQL连接对象</param>
2458         /// <param name="spName">The name of the stored procedure</param>
2459         /// <param name="spName">存储过程名称</param>
2460         /// <param name="sourceColumns">An array of string to be assigned as the source columns of the stored procedure parameters</param>
2461         /// <param name="sourceColumns">用于分配为存储过程参数的源列(source columns)的字符串的集合</param>
2462         /// <returns>A valid SqlCommand object</returns>
2463         /// <returns>返回一个合法的SQL命令对象</returns>
2464         public static SqlCommand CreateCommand(SqlConnection connection, string spName, params string[] sourceColumns) 
2465         {
2466             if( connection == null ) throw new ArgumentNullException( "connection" );
2467             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2468 
2469             // Create a SqlCommand
2470             // 创建一个SQL命令
2471             SqlCommand cmd = new SqlCommand( spName, connection );
2472             cmd.CommandType = CommandType.StoredProcedure;
2473 
2474             // If we receive parameter values, we need to figure out where they go
2475             // 如果收到参数值,则需要指出它们的去向
2476             if ((sourceColumns != null) && (sourceColumns.Length > 0)) 
2477             {
2478                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2479                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2480                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
2481 
2482                 // Assign the provided source columns to these parameters based on parameter order
2483                 // 根据参数的顺序将提供的源列(source columns)分配给这些参数
2484                 for (int index=0; index < sourceColumns.Length; index++)
2485                     commandParameters[index].SourceColumn = sourceColumns[index];
2486 
2487                 // Attach the discovered parameters to the SqlCommand object
2488                 // 将找到的参数附加给SQL命令对象
2489                 AttachParameters (cmd, commandParameters);
2490             }
2491 
2492             return cmd;
2493         }
2494         #endregion
2495 
2496         #region ExecuteNonQueryTypedParams
2497         /// <summary>
2498         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the database specified in 
2499         /// the connection string using the dataRow column values as the stored procedure's parameters values.
2500         /// This method will query the database to discover the parameters for the 
2501         /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.
2502         /// 利用dataRow的列值(作为存储过程的参数值),通过SQL命令(不返回结果集)执行存储过程以取代在连接字符串中指定的数据库.
2503         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2504         /// </summary>
2505         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
2506         /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
2507         /// <param name="spName">The name of the stored procedure</param>
2508         /// <param name="spName">存储过程名称</param>
2509         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
2510         /// <param name="dataRow">用于持有存储过程的参数值的数据行(dataRow).</param>
2511         /// <returns>An int representing the number of rows affected by the command</returns>
2512         /// <returns>返回一个整型数,用于表示被命令影响的列数</returns>
2513         public static int ExecuteNonQueryTypedParams(String connectionString, String spName, DataRow dataRow)
2514         {
2515             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
2516             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2517             
2518             // If the row has values, the store procedure parameters must be initialized
2519                         // 如果行有值,存储过程参数必须被初始化
2520             if (dataRow != null && dataRow.ItemArray.Length > 0)
2521             {
2522                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2523                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2524                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
2525                 
2526                 // Set the parameters values
2527                 // 设定参数的值
2528                 AssignParameterValues(commandParameters, dataRow);
2529                                 
2530                 return SqlHelper.ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters);
2531             }
2532             else
2533             {
2534                 return SqlHelper.ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName);
2535             }
2536         }
2537 
2538         /// <summary>
2539         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified SqlConnection 
2540         /// using the dataRow column values as the stored procedure's parameters values.  
2541         /// This method will query the database to discover the parameters for the 
2542         /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.
2543         /// 利用dataRow的列值(作为存储过程的参数值),通过SQL命令(不返回结果集)执行存储过程以取代指定的SQL连接.
2544         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2545         /// </summary>
2546         /// <param name="connection">A valid SqlConnection object</param>
2547         /// <param name="connection">合法的SQL连接对象</param>
2548         /// <param name="spName">The name of the stored procedure</param>
2549         /// <param name="spName">存储过程名称</param>
2550         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
2551         /// <param name="dataRow">用于持有存储过程的参数值的数据行(dataRow).</param>
2552         /// <returns>An int representing the number of rows affected by the command</returns>
2553         /// <returns>返回一个整型数,用于表示被命令影响的列数</returns>
2554         public static int ExecuteNonQueryTypedParams(SqlConnection connection, String spName, DataRow dataRow)
2555         {
2556             if( connection == null ) throw new ArgumentNullException( "connection" );
2557             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2558 
2559             // If the row has values, the store procedure parameters must be initialized
2560             // 如果行有值,存储过程参数必须被初始化
2561             if (dataRow != null && dataRow.ItemArray.Length > 0)
2562             {
2563                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2564                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2565                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
2566                 
2567                 // Set the parameters values
2568                 // 设定参数的值
2569                 AssignParameterValues(commandParameters, dataRow);
2570                                 
2571                 return SqlHelper.ExecuteNonQuery(connection, CommandType.StoredProcedure, spName, commandParameters);
2572             }
2573             else
2574             {
2575                 return SqlHelper.ExecuteNonQuery(connection, CommandType.StoredProcedure, spName);
2576             }
2577         }
2578 
2579         /// <summary>
2580         /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified
2581         /// SqlTransaction using the dataRow column values as the stored procedure's parameters values.
2582         /// This method will query the database to discover the parameters for the 
2583         /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.
2584         /// 利用dataRow的列值(作为存储过程的参数值),通过SQL命令(不返回结果集)执行存储过程以取代指定的SQL事务.
2585         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2586         /// </summary>
2587         /// <param name="transaction">A valid SqlTransaction object</param>
2588         /// <param name="transaction">合法的SQL事务对象</param>
2589         /// <param name="spName">The name of the stored procedure</param>
2590         /// <param name="spName">存储过程名称</param>
2591         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
2592         /// <param name="dataRow">用于持有存储过程的参数值的数据行(dataRow).</param>
2593         /// <returns>An int representing the number of rows affected by the command</returns>
2594         /// <returns>返回一个整型数,用于表示被命令影响的列数</returns>
2595         public static int ExecuteNonQueryTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
2596         {
2597             if( transaction == null ) throw new ArgumentNullException( "transaction" );
2598             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
2599             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2600 
2601             // If the row has values, the store procedure parameters must be initialized
2602             // 如果行有值,存储过程参数必须被初始化
2603             if (dataRow != null && dataRow.ItemArray.Length > 0)
2604             {
2605                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2606                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2607                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
2608                 
2609                 // Set the parameters values
2610                 // 设定参数的值
2611                 AssignParameterValues(commandParameters, dataRow);
2612                                 
2613                 return SqlHelper.ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName, commandParameters);
2614             }
2615             else
2616             {
2617                 return SqlHelper.ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName);
2618             }
2619         }
2620         #endregion
2621 
2622         #region ExecuteDatasetTypedParams
2623         /// <summary>
2624         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 
2625         /// the connection string using the dataRow column values as the stored procedure's parameters values.
2626         /// This method will query the database to discover the parameters for the 
2627         /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.
2628         /// 利用dataRow的列值(作为存储过程的参数值),通过SQL命令(返回一个结果集)执行存储过程以取代在连接字符串中指定的数据库.
2629         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2630         /// </summary>
2631         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
2632         /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
2633         /// <param name="spName">The name of the stored procedure</param>
2634         /// <param name="spName">存储过程名称</param>
2635         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
2636         /// <param name="dataRow">用于持有存储过程的参数值的数据行(dataRow).</param>
2637         /// <returns>A dataset containing the resultset generated by the command</returns>
2638         /// <returns>返回一个包含由命令生成的结果集的数据集(dataset)</returns>
2639         public static DataSet ExecuteDatasetTypedParams(string connectionString, String spName, DataRow dataRow)
2640         {
2641             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
2642             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2643 
2644             //If the row has values, the store procedure parameters must be initialized
2645             // 如果行有值,存储过程参数必须被初始化
2646             if ( dataRow != null && dataRow.ItemArray.Length > 0)
2647             {
2648                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2649                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2650                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
2651                 
2652                 // Set the parameters values
2653                 // 设定参数的值
2654                 AssignParameterValues(commandParameters, dataRow);
2655                 
2656                 return SqlHelper.ExecuteDataset(connectionString, CommandType.StoredProcedure, spName, commandParameters);
2657             }
2658             else
2659             {
2660                 return SqlHelper.ExecuteDataset(connectionString, CommandType.StoredProcedure, spName);
2661             }
2662         }
2663 
2664         /// <summary>
2665         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
2666         /// using the dataRow column values as the store procedure's parameters values.
2667         /// This method will query the database to discover the parameters for the 
2668         /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.
2669         /// 利用dataRow的列值(作为存储过程的参数值),通过SQL命令(返回一个结果集)执行存储过程以取代指定的SQL连接.
2670         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2671         /// </summary>
2672         /// <param name="connection">A valid SqlConnection object</param>
2673         /// <param name="connection">合法的SQL连接对象</param>
2674         /// <param name="spName">The name of the stored procedure</param>
2675         /// <param name="spName">存储过程名称</param>
2676         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
2677         /// <param name="dataRow">用于持有存储过程的参数值的数据行(dataRow).</param>
2678         /// <returns>A dataset containing the resultset generated by the command</returns>
2679         /// <returns>返回一个包含由命令生成的结果集的数据集(dataset)</returns>
2680         public static DataSet ExecuteDatasetTypedParams(SqlConnection connection, String spName, DataRow dataRow)
2681         {
2682             if( connection == null ) throw new ArgumentNullException( "connection" );
2683             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2684 
2685             // If the row has values, the store procedure parameters must be initialized
2686             // 如果行有值,存储过程参数必须被初始化
2687             if( dataRow != null && dataRow.ItemArray.Length > 0)
2688             {
2689                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2690                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2691                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
2692                 
2693                 // Set the parameters values
2694                 // 设定参数的值
2695                 AssignParameterValues(commandParameters, dataRow);
2696                 
2697                 return SqlHelper.ExecuteDataset(connection, CommandType.StoredProcedure, spName, commandParameters);
2698             }
2699             else
2700             {
2701                 return SqlHelper.ExecuteDataset(connection, CommandType.StoredProcedure, spName);
2702             }
2703         }
2704 
2705         /// <summary>
2706         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlTransaction 
2707         /// using the dataRow column values as the stored procedure's parameters values.
2708         /// This method will query the database to discover the parameters for the 
2709         /// stored procedure (the first time each stored procedure is called), and assign the values based on row values.
2710         /// 利用dataRow的列值(作为存储过程的参数值),通过SQL命令(返回一个结果集)执行存储过程以取代指定的SQL事务.
2711         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2712         /// </summary>
2713         /// <param name="transaction">A valid SqlTransaction object</param>
2714         /// <param name="transaction">合法的SQL事务对象</param>
2715         /// <param name="spName">The name of the stored procedure</param>
2716         /// <param name="spName">存储过程名称</param>
2717         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
2718         /// <param name="dataRow">用于持有存储过程的参数值的数据行(dataRow).</param>
2719         /// <returns>A dataset containing the resultset generated by the command</returns>
2720         /// <returns>返回一个包含由命令生成的结果集的数据集(dataset)</returns>
2721         public static DataSet ExecuteDatasetTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
2722         {
2723             if( transaction == null ) throw new ArgumentNullException( "transaction" );
2724             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
2725             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2726 
2727             // If the row has values, the store procedure parameters must be initialized
2728             // 如果行有值,存储过程参数必须被初始化
2729             if( dataRow != null && dataRow.ItemArray.Length > 0)
2730             {
2731                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2732                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2733                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
2734                 
2735                 // Set the parameters values
2736                 // 设定参数的值
2737                 AssignParameterValues(commandParameters, dataRow);
2738                 
2739                 return SqlHelper.ExecuteDataset(transaction, CommandType.StoredProcedure, spName, commandParameters);
2740             }
2741             else
2742             {
2743                 return SqlHelper.ExecuteDataset(transaction, CommandType.StoredProcedure, spName);
2744             }
2745         }
2746 
2747         #endregion
2748 
2749         #region ExecuteReaderTypedParams
2750         /// <summary>
2751         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 
2752         /// the connection string using the dataRow column values as the stored procedure's parameters values.
2753         /// This method will query the database to discover the parameters for the 
2754         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
2755         /// 利用dataRow的列值(作为存储过程的参数值),通过SQL命令(返回一个结果集)执行存储过程以取代在连接字符串中指定的数据库.
2756         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2757         /// </summary>
2758         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
2759         /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
2760         /// <param name="spName">The name of the stored procedure</param>
2761         /// <param name="spName">存储过程名称</param>
2762         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
2763         /// <param name="dataRow">用于持有存储过程的参数值的数据行(dataRow).</param>
2764         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
2765         /// <returns>返回一个包含由命令生成的结果集的SqlDataReader</returns>
2766         public static SqlDataReader ExecuteReaderTypedParams(String connectionString, String spName, DataRow dataRow)
2767         {
2768             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
2769             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2770             
2771             // If the row has values, the store procedure parameters must be initialized
2772                         // 如果行有值,存储过程参数必须被初始化
2773             if ( dataRow != null && dataRow.ItemArray.Length > 0 )
2774             {
2775                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2776                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2777                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
2778                 
2779                 // Set the parameters values
2780                 // 设定参数的值
2781                 AssignParameterValues(commandParameters, dataRow);
2782                 
2783                 return SqlHelper.ExecuteReader(connectionString, CommandType.StoredProcedure, spName, commandParameters);
2784             }
2785             else
2786             {
2787                 return SqlHelper.ExecuteReader(connectionString, CommandType.StoredProcedure, spName);
2788             }
2789         }
2790 
2791                 
2792         /// <summary>
2793         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
2794         /// using the dataRow column values as the stored procedure's parameters values.
2795         /// This method will query the database to discover the parameters for the 
2796         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
2797         /// 利用dataRow的列值(作为存储过程的参数值),通过SQL命令(返回一个结果集)执行存储过程以取代指定的SQL连接.
2798         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2799         /// </summary>
2800         /// <param name="connection">A valid SqlConnection object</param>
2801         /// <param name="connection">合法的SQL连接对象</param>
2802         /// <param name="spName">The name of the stored procedure</param>
2803         /// <param name="spName">存储过程名称</param>
2804         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
2805         /// <param name="dataRow">用于持有存储过程的参数值的数据行(dataRow).</param>
2806         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
2807         /// <returns>返回一个包含由命令生成的结果集的SqlDataReader</returns>
2808         public static SqlDataReader ExecuteReaderTypedParams(SqlConnection connection, String spName, DataRow dataRow)
2809         {
2810             if( connection == null ) throw new ArgumentNullException( "connection" );
2811             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2812 
2813             // If the row has values, the store procedure parameters must be initialized
2814             // 如果行有值,存储过程参数必须被初始化
2815             if( dataRow != null && dataRow.ItemArray.Length > 0)
2816             {
2817                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2818                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2819                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
2820                 
2821                 // Set the parameters values
2822                 // 设定参数的值
2823                 AssignParameterValues(commandParameters, dataRow);
2824                 
2825                 return SqlHelper.ExecuteReader(connection, CommandType.StoredProcedure, spName, commandParameters);
2826             }
2827             else
2828             {
2829                 return SqlHelper.ExecuteReader(connection, CommandType.StoredProcedure, spName);
2830             }
2831         }
2832         
2833         /// <summary>
2834         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlTransaction 
2835         /// using the dataRow column values as the stored procedure's parameters values.
2836         /// This method will query the database to discover the parameters for the 
2837         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
2838         /// 利用dataRow的列值(作为存储过程的参数值),通过SQL命令(返回一个结果集)执行存储过程以取代指定的SQL事务.
2839         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2840         /// </summary>
2841         /// <param name="transaction">A valid SqlTransaction object</param>
2842         /// <param name="transaction">合法的SQL事务对象</param>
2843         /// <param name="spName">The name of the stored procedure</param>
2844         /// <param name="spName">存储过程名称</param>
2845         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
2846         /// <param name="dataRow">用于持有存储过程的参数值的数据行(dataRow).</param>
2847         /// <returns>A SqlDataReader containing the resultset generated by the command</returns>
2848         /// <returns>返回一个包含由命令生成的结果集的SqlDataReader</returns>
2849         public static SqlDataReader ExecuteReaderTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
2850         {
2851             if( transaction == null ) throw new ArgumentNullException( "transaction" );
2852             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
2853             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2854 
2855             // If the row has values, the store procedure parameters must be initialized
2856             // 如果行有值,存储过程参数必须被初始化
2857             if( dataRow != null && dataRow.ItemArray.Length > 0 )
2858             {
2859                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2860                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2861                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
2862                 
2863                 // Set the parameters values
2864                 // 设定参数的值
2865                 AssignParameterValues(commandParameters, dataRow);
2866                 
2867                 return SqlHelper.ExecuteReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
2868             }
2869             else
2870             {
2871                 return SqlHelper.ExecuteReader(transaction, CommandType.StoredProcedure, spName);
2872             }
2873         }
2874         #endregion
2875 
2876         #region ExecuteScalarTypedParams
2877         /// <summary>
2878         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the database specified in 
2879         /// the connection string using the dataRow column values as the stored procedure's parameters values.
2880         /// This method will query the database to discover the parameters for the 
2881         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
2882         /// 利用dataRow的列值(作为存储过程的参数值),通过SQL命令(返回一个1x1的结果集)执行存储过程以取代在连接字符串中指定的数据库.
2883         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2884         /// </summary>
2885         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
2886         /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
2887         /// <param name="spName">The name of the stored procedure</param>
2888         /// <param name="spName">存储过程名称</param>
2889         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
2890         /// <param name="dataRow">用于持有存储过程的参数值的数据行(dataRow).</param>
2891         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
2892         /// <returns>返回一个对象,此对象包含由命令生成的1x1的结果集中的值</returns>
2893         public static object ExecuteScalarTypedParams(String connectionString, String spName, DataRow dataRow)
2894         {
2895             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
2896             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2897             
2898             // If the row has values, the store procedure parameters must be initialized
2899                         // 如果行有值,存储过程参数必须被初始化
2900             if( dataRow != null && dataRow.ItemArray.Length > 0)
2901             {
2902                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2903                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2904                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
2905                 
2906                 // Set the parameters values
2907                 // 设定参数的值
2908                 AssignParameterValues(commandParameters, dataRow);
2909                 
2910                 return SqlHelper.ExecuteScalar(connectionString, CommandType.StoredProcedure, spName, commandParameters);
2911             }
2912             else
2913             {
2914                 return SqlHelper.ExecuteScalar(connectionString, CommandType.StoredProcedure, spName);
2915             }
2916         }
2917 
2918         /// <summary>
2919         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection 
2920         /// using the dataRow column values as the stored procedure's parameters values.
2921         /// This method will query the database to discover the parameters for the 
2922         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
2923         /// 利用dataRow的列值(作为存储过程的参数值),通过SQL命令(返回一个1x1的结果集)执行存储过程以取代指定的SQL连接.
2924         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2925         /// </summary>
2926         /// <param name="connection">A valid SqlConnection object</param>
2927         /// <param name="connection">合法的SQL连接对象</param>
2928         /// <param name="spName">The name of the stored procedure</param>
2929         /// <param name="spName">存储过程名称</param>
2930         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
2931         /// <param name="dataRow">用于持有存储过程的参数值的数据行(dataRow).</param>
2932         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
2933         /// <returns>返回一个对象,此对象包含由命令生成的1x1的结果集中的值</returns>
2934         public static object ExecuteScalarTypedParams(SqlConnection connection, String spName, DataRow dataRow)
2935         {
2936             if( connection == null ) throw new ArgumentNullException( "connection" );
2937             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2938 
2939             // If the row has values, the store procedure parameters must be initialized
2940             // 如果行有值,存储过程参数必须被初始化
2941             if( dataRow != null && dataRow.ItemArray.Length > 0)
2942             {
2943                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2944                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2945                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
2946                 
2947                 // Set the parameters values
2948                 // 设定参数的值
2949                 AssignParameterValues(commandParameters, dataRow);
2950                 
2951                 return SqlHelper.ExecuteScalar(connection, CommandType.StoredProcedure, spName, commandParameters);
2952             }
2953             else
2954             {
2955                 return SqlHelper.ExecuteScalar(connection, CommandType.StoredProcedure, spName);
2956             }
2957         }
2958 
2959         /// <summary>
2960         /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified SqlTransaction
2961         /// using the dataRow column values as the stored procedure's parameters values.
2962         /// This method will query the database to discover the parameters for the 
2963         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
2964         /// 利用dataRow的列值(作为存储过程的参数值),通过SQL命令(返回一个1x1的结果集)执行存储过程以取代指定的SQL事务.
2965         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
2966         /// </summary>
2967         /// <param name="transaction">A valid SqlTransaction object</param>
2968         /// <param name="transaction">合法的SQL事务对象</param>
2969         /// <param name="spName">The name of the stored procedure</param>
2970         /// <param name="spName">存储过程名称</param>
2971         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
2972         /// <param name="dataRow">用于持有存储过程的参数值的数据行(dataRow).</param>
2973         /// <returns>An object containing the value in the 1x1 resultset generated by the command</returns>
2974         /// <returns>返回一个对象,此对象包含由命令生成的1x1的结果集中的值</returns>
2975         public static object ExecuteScalarTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
2976         {
2977             if( transaction == null ) throw new ArgumentNullException( "transaction" );
2978             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
2979             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
2980 
2981             // If the row has values, the store procedure parameters must be initialized
2982             // 如果行有值,存储过程参数必须被初始化
2983             if( dataRow != null && dataRow.ItemArray.Length > 0)
2984             {
2985                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
2986                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
2987                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
2988                 
2989                 // Set the parameters values
2990                 // 设定参数的值
2991                 AssignParameterValues(commandParameters, dataRow);
2992                 
2993                 return SqlHelper.ExecuteScalar(transaction, CommandType.StoredProcedure, spName, commandParameters);
2994             }
2995             else
2996             {
2997                 return SqlHelper.ExecuteScalar(transaction, CommandType.StoredProcedure, spName);
2998             }
2999         }
3000         #endregion
3001 
3002         #region ExecuteXmlReaderTypedParams
3003         /// <summary>
3004         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection 
3005         /// using the dataRow column values as the stored procedure's parameters values.
3006         /// This method will query the database to discover the parameters for the 
3007         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
3008         /// 利用dataRow的列值(作为存储过程的参数值),通过SQL命令(返回一个结果集)执行存储过程以取代指定的SQL连接.
3009         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
3010         /// </summary>
3011         /// <param name="connection">A valid SqlConnection object</param>
3012         /// <param name="connection">合法的SQL连接对象</param>
3013         /// <param name="spName">The name of the stored procedure</param>
3014         /// <param name="spName">存储过程名称</param>
3015         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
3016         /// <param name="dataRow">用于持有存储过程的参数值的数据行(dataRow).</param>
3017         /// <returns>An XmlReader containing the resultset generated by the command</returns>
3018         /// <returns>包含有命令生成的结果集的XmlReader</returns>
3019         public static XmlReader ExecuteXmlReaderTypedParams(SqlConnection connection, String spName, DataRow dataRow)
3020         {
3021             if( connection == null ) throw new ArgumentNullException( "connection" );
3022             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
3023 
3024             // If the row has values, the store procedure parameters must be initialized
3025             // 如果行有值,存储过程参数必须被初始化
3026             if( dataRow != null && dataRow.ItemArray.Length > 0)
3027             {
3028                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
3029                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
3030                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
3031                 
3032                 // Set the parameters values
3033                 // 设定参数的值
3034                 AssignParameterValues(commandParameters, dataRow);
3035                 
3036                 return SqlHelper.ExecuteXmlReader(connection, CommandType.StoredProcedure, spName, commandParameters);
3037             }
3038             else
3039             {
3040                 return SqlHelper.ExecuteXmlReader(connection, CommandType.StoredProcedure, spName);
3041             }
3042         }
3043 
3044         /// <summary>
3045         /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlTransaction 
3046         /// using the dataRow column values as the stored procedure's parameters values.
3047         /// This method will query the database to discover the parameters for the 
3048         /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
3049         /// 利用dataRow的列值(作为存储过程的参数值),通过SQL命令(返回一个结果集)执行存储过程以取代指定的SQL事务.
3050         /// 此方法查询数据库以发现为存储过程提供的参数(每个存储过程第一次被调用时),并依参数顺序给它们分配值.
3051         /// </summary>
3052         /// <param name="transaction">A valid SqlTransaction object</param>
3053         /// <param name="transaction">合法的SQL事务对象</param>
3054         /// <param name="spName">The name of the stored procedure</param>
3055         /// <param name="spName">存储过程名称</param>
3056         /// <param name="dataRow">The dataRow used to hold the stored procedure's parameter values.</param>
3057         /// <param name="dataRow">用于持有存储过程的参数值的数据行(dataRow).</param>
3058         /// <returns>An XmlReader containing the resultset generated by the command</returns>
3059         /// <returns>返回包含有命令生成的结果集的XmlReader</returns>
3060         public static XmlReader ExecuteXmlReaderTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
3061         {
3062             if( transaction == null ) throw new ArgumentNullException( "transaction" );
3063             if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" );
3064             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
3065 
3066             // If the row has values, the store procedure parameters must be initialized
3067             // 如果行有值,存储过程参数必须被初始化
3068             if( dataRow != null && dataRow.ItemArray.Length > 0)
3069             {
3070                 // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
3071                 // 为存储过程将参数从参数缓存中拖出(或找到它们并将它们的缓存地公开)
3072                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
3073                 
3074                 // Set the parameters values
3075                 // 设定参数的值
3076                 AssignParameterValues(commandParameters, dataRow);
3077                 
3078                 return SqlHelper.ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
3079             }
3080             else
3081             {
3082                 return SqlHelper.ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName);
3083             }
3084         }
3085         #endregion
3086 
3087     }
3088 
3089     /// <summary>
3090     /// SqlHelperParameterCache provides functions to leverage a static cache of procedure parameters, and the
3091     /// ability to discover parameters for stored procedures at run-time.
3092         /// SqlHelperParameterCache提供函数以调节(leverage)静态的过程参数的缓存和在线发现存储过程参数的能力,
3093     /// </summary>
3094     public sealed class SqlHelperParameterCache
3095     {
3096         #region private methods, variables, and constructors
3097 
3098         //Since this class provides only static methods, make the default constructor private to prevent 
3099         //instances from being created with "new SqlHelperParameterCache()"
3100                 // 因为此类只提供静态方法,使得默认的构造器变为私有,从而防止实例由"new SqlHelperParameterCache()"方法创建
3101         private SqlHelperParameterCache() {}
3102 
3103         private static Hashtable paramCache = Hashtable.Synchronized(new Hashtable());
3104 
3105         /// <summary>
3106         /// Resolve at run time the appropriate set of SqlParameters for a stored procedure
3107         /// 为存储过程在线确定合适的SQL参数集
3108         /// </summary>
3109         /// <param name="connection">A valid SqlConnection object</param>
3110         /// <param name="connection">合法的SQL连接对象</param>
3111         /// <param name="spName">The name of the stored procedure</param>
3112         /// <param name="spName">存储过程名称</param>
3113         /// <param name="includeReturnValueParameter">Whether or not to include their return value parameter</param>
3114         /// <param name="includeReturnValueParameter">是否包括他们的返回值参数</param>
3115         /// <returns>The parameter array discovered.</returns>
3116         /// <returns>返回找到的参数集.</returns>
3117         private static SqlParameter[] DiscoverSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter)
3118         {
3119             if( connection == null ) throw new ArgumentNullException( "connection" );
3120             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
3121 
3122             SqlCommand cmd = new SqlCommand(spName, connection);
3123             cmd.CommandType = CommandType.StoredProcedure;
3124 
3125             connection.Open();
3126             SqlCommandBuilder.DeriveParameters(cmd);
3127             connection.Close();
3128 
3129             if (!includeReturnValueParameter) 
3130             {
3131                 cmd.Parameters.RemoveAt(0);
3132             }
3133                 
3134             SqlParameter[] discoveredParameters = new SqlParameter[cmd.Parameters.Count];
3135 
3136             cmd.Parameters.CopyTo(discoveredParameters, 0);
3137 
3138             // Init the parameters with a DBNull value
3139                         // 用DBNull值初始化参数
3140             foreach (SqlParameter discoveredParameter in discoveredParameters)
3141             {
3142                 discoveredParameter.Value = DBNull.Value;
3143             }
3144             return discoveredParameters;
3145         }
3146 
3147         /// <summary>
3148         /// Deep copy of cached SqlParameter array
3149                 /// 缓存(cache)的参数集的深拷贝(Deep copy)
3150         /// </summary>
3151         /// <param name="originalParameters"></param>
3152         /// <returns></returns>
3153         private static SqlParameter[] CloneParameters(SqlParameter[] originalParameters)
3154         {
3155             SqlParameter[] clonedParameters = new SqlParameter[originalParameters.Length];
3156 
3157             for (int i = 0, j = originalParameters.Length; i < j; i++)
3158             {
3159                 clonedParameters[i] = (SqlParameter)((ICloneable)originalParameters[i]).Clone();
3160             }
3161 
3162             return clonedParameters;
3163         }
3164 
3165         #endregion private methods, variables, and constructors
3166 
3167         #region caching functions
3168 
3169         /// <summary>
3170         /// Add parameter array to the cache
3171                 /// 添加参数集给缓存
3172         /// </summary>
3173         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
3174                 /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
3175         /// <param name="commandText">The stored procedure name or T-SQL command</param>
3176                 /// <param name="commandText">存储过程名称或T-SQL命令</param>
3177         /// <param name="commandParameters">An array of SqlParamters to be cached</param>
3178         /// <param name="commandParameters">将要被缓存的SQL参数集</param>
3179         public static void CacheParameterSet(string connectionString, string commandText, params SqlParameter[] commandParameters)
3180         {
3181             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
3182             if( commandText == null || commandText.Length == 0 ) throw new ArgumentNullException( "commandText" );
3183 
3184             string hashKey = connectionString + ":" + commandText;
3185 
3186             paramCache[hashKey] = commandParameters;
3187         }
3188 
3189         /// <summary>
3190         /// Retrieve a parameter array from the cache
3191                 /// 从缓存中检索参数集
3192         /// </summary>
3193         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
3194                 /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
3195         /// <param name="commandText">The stored procedure name or T-SQL command</param>
3196                 /// <param name="commandText">存储过程名称或T-SQL命令</param>
3197         /// <returns>An array of SqlParamters</returns>
3198                 /// <returns>返回一个SQL参数集</returns>
3199         public static SqlParameter[] GetCachedParameterSet(string connectionString, string commandText)
3200         {
3201             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
3202             if( commandText == null || commandText.Length == 0 ) throw new ArgumentNullException( "commandText" );
3203 
3204             string hashKey = connectionString + ":" + commandText;
3205 
3206             SqlParameter[] cachedParameters = paramCache[hashKey] as SqlParameter[];
3207             if (cachedParameters == null)
3208             {            
3209                 return null;
3210             }
3211             else
3212             {
3213                 return CloneParameters(cachedParameters);
3214             }
3215         }
3216 
3217         #endregion caching functions
3218 
3219         #region Parameter Discovery Functions
3220 
3221         /// <summary>
3222         /// Retrieves the set of SqlParameters appropriate for the stored procedure
3223                 /// 为存储过程检索适当的SQL参数集
3224         /// </summary>
3225         /// <remarks>
3226         /// This method will query the database for this information, and then store it in a cache for future requests.
3227                 /// 此方法查询数据库以获取信息,然后将其存在缓存中以便以后查询使用
3228         /// </remarks>
3229         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
3230                 /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
3231         /// <param name="spName">The name of the stored procedure</param>
3232         /// <param name="spName">存储过程的名称</param>
3233         /// <returns>An array of SqlParameters</returns>
3234         /// <returns>返回一个SQL参数集</returns>
3235         public static SqlParameter[] GetSpParameterSet(string connectionString, string spName)
3236         {
3237             return GetSpParameterSet(connectionString, spName, false);
3238         }
3239 
3240         /// <summary>
3241         /// Retrieves the set of SqlParameters appropriate for the stored procedure
3242                 /// 为存储过程检索适当的SQL参数集
3243         /// </summary>
3244         /// <remarks>
3245         /// This method will query the database for this information, and then store it in a cache for future requests.
3246                 /// 此方法查询数据库以获取信息,然后将其存在缓存中以便以后查询使用.
3247         /// </remarks>
3248         /// <param name="connectionString">A valid connection string for a SqlConnection</param>
3249                 /// <param name="connectionString">一个用于SQL连接的合法的连接字符串</param>
3250         /// <param name="spName">The name of the stored procedure</param>/
3251         /// <param name="spName">存储过程的名称</param>
3252         /// <param name="includeReturnValueParameter">A bool value indicating whether the return value parameter should be included in the results</param>
3253         /// <param name="includeReturnValueParameter">一个bool值,指示返回值参数是否应被包括在结果集中</param>
3254         /// <returns>An array of SqlParameters</returns>
3255         /// <returns>返回一个SQL参数集</returns>
3256         public static SqlParameter[] GetSpParameterSet(string connectionString, string spName, bool includeReturnValueParameter)
3257         {
3258             if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );
3259             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
3260 
3261             using(SqlConnection connection = new SqlConnection(connectionString))
3262             {
3263                 return GetSpParameterSetInternal(connection, spName, includeReturnValueParameter);
3264             }
3265         }
3266 
3267         /// <summary>
3268         /// Retrieves the set of SqlParameters appropriate for the stored procedure
3269         /// 为存储过程检索适当的SQL参数集
3270         /// </summary>
3271         /// <remarks>
3272         /// This method will query the database for this information, and then store it in a cache for future requests.
3273         /// 此方法查询数据库以获取信息,然后将其存在缓存中以便以后查询使用.
3274         /// </remarks>
3275         /// <param name="connection">A valid SqlConnection object</param>
3276         /// <param name="connection">合法的SQL连接对象</param>
3277         /// <param name="spName">The name of the stored procedure</param>
3278         /// <param name="spName">存储过程名称</param>
3279         /// <returns>An array of SqlParameters</returns>
3280     /// <returns>返回一个SQL参数集</returns>
3281         internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName)
3282         {
3283             return GetSpParameterSet(connection, spName, false);
3284         }
3285 
3286         /// <summary>
3287         /// Retrieves the set of SqlParameters appropriate for the stored procedure
3288         /// 为存储过程检索适当的SQL参数集
3289         /// </summary>
3290         /// <remarks>
3291         /// This method will query the database for this information, and then store it in a cache for future requests.
3292         /// 此方法查询数据库以获取信息,然后将其存在缓存中以便以后查询使用.
3293         /// </remarks>
3294         /// <param name="connection">A valid SqlConnection object</param>
3295         /// <param name="connection">合法的SQL连接对象</param>
3296         /// <param name="spName">The name of the stored procedure</param>
3297         /// <param name="spName">存储过程名称</param>
3298         /// <param name="includeReturnValueParameter">A bool value indicating whether the return value parameter should be included in the results</param>
3299     /// <param name="includeReturnValueParameter">一个bool值,指示返回值参数是否应被包括在结果集中</param>
3300         /// <returns>An array of SqlParameters</returns>
3301     /// <returns>返回一个SQL参数集</returns>
3302         internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter)
3303         {
3304             if( connection == null ) throw new ArgumentNullException( "connection" );
3305             using (SqlConnection clonedConnection = (SqlConnection)((ICloneable)connection).Clone())
3306             {
3307                 return GetSpParameterSetInternal(clonedConnection, spName, includeReturnValueParameter);
3308             }
3309         }
3310 
3311         /// <summary>
3312         /// Retrieves the set of SqlParameters appropriate for the stored procedure
3313         /// 为存储过程检索适当的SQL参数集
3314         /// </summary>
3315         /// <param name="connection">A valid SqlConnection object</param>
3316         /// <param name="connection">合法的SQL连接对象</param>
3317         /// <param name="spName">The name of the stored procedure</param>
3318         /// <param name="spName">存储过程名称</param>
3319         /// <param name="includeReturnValueParameter">A bool value indicating whether the return value parameter should be included in the results</param>
3320     /// <param name="includeReturnValueParameter">一个bool值,指示返回值参数是否应被包括在结果集中</param>
3321         /// <returns>An array of SqlParameters</returns>
3322     /// <returns>返回一个SQL参数集</returns>
3323         private static SqlParameter[] GetSpParameterSetInternal(SqlConnection connection, string spName, bool includeReturnValueParameter)
3324         {
3325             if( connection == null ) throw new ArgumentNullException( "connection" );
3326             if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" );
3327 
3328             string hashKey = connection.ConnectionString + ":" + spName + (includeReturnValueParameter ? ":include ReturnValue Parameter":"");
3329 
3330             SqlParameter[] cachedParameters;
3331             
3332             cachedParameters = paramCache[hashKey] as SqlParameter[];
3333             if (cachedParameters == null)
3334             {    
3335                 SqlParameter[] spParameters = DiscoverSpParameterSet(connection, spName, includeReturnValueParameter);
3336                 paramCache[hashKey] = spParameters;
3337                 cachedParameters = spParameters;
3338             }
3339             
3340             return CloneParameters(cachedParameters);
3341         }
3342         
3343         #endregion Parameter Discovery Functions
3344 
3345     }
3346 }
SqlHelper和SqlHelperParameterCache类

 

简单SqlHelper

  1 using System;
  2 using System.Data;
  3 using System.Data.SqlClient;
  4 using System.Linq;
  5 using System.Net.Sockets;
  6 
  7 namespace Itcast.Mall.Utility
  8 {
  9     /// <summary>
 10     /// SQL Server数据库访问助手类
 11     /// 本类为静态类 不可以被实例化 需要使用时直接调用即可
 12     /// Copyright © 2013 Wedn.Net
 13     /// </summary>
 14     public static partial class SqlHelper
 15     {
 16         private static readonly string[] localhost = new[] { "localhost", ".", "(local)" };
 17         /// <summary>
 18         /// 数据库连接字符串
 19         /// </summary>
 20         private readonly static string connStr;
 21         static SqlHelper()
 22         {
 23             var conn = System.Configuration.ConfigurationManager.ConnectionStrings["ConnStr"];
 24             if (conn!=null)
 25             {
 26                 connStr = conn.ConnectionString;
 27             }
 28         }
 29 
 30         #region 数据库检测
 31 
 32         #region 测试数据库服务器连接 +static bool TestConnection(string host, int port, int millisecondsTimeout)
 33         /// <summary> 
 34         /// 采用Socket方式,测试数据库服务器连接 
 35         /// </summary> 
 36         /// <param name="host">服务器主机名或IP</param> 
 37         /// <param name="port">端口号</param> 
 38         /// <param name="millisecondsTimeout">等待时间:毫秒</param> 
 39         /// <exception cref="Exception">链接异常</exception>
 40         /// <returns></returns> 
 41         public static bool TestConnection(string host, int port, int millisecondsTimeout)
 42         {
 43             host = localhost.Contains(host) ? "127.0.0.1" : host;
 44             using (var client = new TcpClient())
 45             {
 46                 try
 47                 {
 48                     var ar = client.BeginConnect(host, port, null, null);
 49                     ar.AsyncWaitHandle.WaitOne(millisecondsTimeout);
 50                     return client.Connected;
 51                 }
 52                 catch (Exception)
 53                 {
 54                     throw;
 55                 }
 56             }
 57         }
 58         #endregion
 59 
 60         #region 检测表是否存在 + static bool ExistsTable(string table)
 61         /// <summary>
 62         /// 检测表是否存在
 63         /// </summary>
 64         /// <param name="table">要检测的表名</param>
 65         /// <returns></returns>
 66         public static bool ExistsTable(string table)
 67         {
 68             string sql = "select count(1) from sysobjects where id = object_id(N'[" + table + "]') and OBJECTPROPERTY(id, N'IsUserTable') = 1";
 69             //string strsql = "SELECT count(*) FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[" + TableName + "]') AND type in (N'U')";
 70             object res = ExecuteScalar(sql);
 71             return (Object.Equals(res, null)) || (Object.Equals(res, System.DBNull.Value));
 72         }
 73         #endregion
 74 
 75         #region 判断是否存在某张表的某个字段 +static bool ExistsColumn(string table, string column)
 76         /// <summary>
 77         /// 判断是否存在某张表的某个字段
 78         /// </summary>
 79         /// <param name="table">表名称</param>
 80         /// <param name="column">列名称</param>
 81         /// <returns>是否存在</returns>
 82         public static bool ExistsColumn(string table, string column)
 83         {
 84             string sql = "select count(1) from syscolumns where [id]=object_id('N[" + table + "]') and [name]='" + column + "'";
 85             object res = ExecuteScalar(sql);
 86             if (res == null)
 87                 return false;
 88             return Convert.ToInt32(res) > 0;
 89         }
 90         #endregion
 91 
 92         #region 判断某张表的某个字段中是否存在某个值 +static bool ColumnExistsValue(string table, string column, string value)
 93         /// <summary>
 94         /// 判断某张表的某个字段中是否存在某个值
 95         /// </summary>
 96         /// <param name="table">表名称</param>
 97         /// <param name="column">列名称</param>
 98         /// <param name="value">要判断的值</param>
 99         /// <returns>是否存在</returns>
100         public static bool ColumnExistsValue(string table, string column, string value)
101         {
102             string sql = "SELECT count(1) FROM [" + table + "] WHERE [" + column + "]=@Value;";
103             object res = ExecuteScalar(sql, new SqlParameter("@Value", value));
104             if (res == null)
105                 return false;
106             return Convert.ToInt32(res) > 0;
107         }
108         #endregion
109 
110         #endregion
111 
112         #region 公共方法
113 
114         #region 获取指定表中指定字段的最大值, 确保字段为INT类型
115         /// <summary>
116         /// 获取指定表中指定字段的最大值, 确保字段为INT类型
117         /// </summary>
118         /// <param name="fieldName">字段名</param>
119         /// <param name="tableName">表名</param>
120         /// <returns>最大值</returns>
121         public static int QueryMaxId(string fieldName, string tableName)
122         {
123             string sql = string.Format("select max([{0}]) from [{1}];", fieldName, tableName);
124             object res = ExecuteScalar(sql);
125             if (res == null)
126                 return 0;
127             return Convert.ToInt32(res);
128         }
129         #endregion
130 
131         #region 生成查询语句
132 
133         #region 生成分页查询数据库语句 +static string GenerateQuerySql(string table, string[] columns, int index, int size, string wheres, string orderField, bool isDesc = true)
134         /// <summary>
135         /// 生成分页查询数据库语句, 返回生成的T-SQL语句
136         /// </summary>
137         /// <param name="table">表名</param>
138         /// <param name="columns">列集合, 多个列用英文逗号分割(colum1,colum2...)</param>
139         /// <param name="index">页码(即第几页)(传入-1则表示忽略分页取出全部)</param>
140         /// <param name="size">显示页面大小(即显示条数)</param>
141         /// <param name="where">条件语句(忽略则传入null)</param>
142         /// <param name="orderField">排序字段(即根据那个字段排序)(忽略则传入null)</param>
143         /// <param name="isDesc">排序方式(0:降序(desc)|1:升序(asc))(忽略则传入-1)</param>
144         /// <returns>生成的T-SQL语句</returns>
145         public static string GenerateQuerySql(string table, string[] columns, int index, int size, string where, string orderField, bool isDesc = true)
146         {
147             if (index == 1)
148             {
149                 // 生成查询第一页SQL
150                 return GenerateQuerySql(table, columns, size, where, orderField, isDesc);
151             }
152             if (index < 1)
153             {
154                 // 取全部数据
155                 return GenerateQuerySql(table, columns, where, orderField, isDesc);
156             }
157             if (string.IsNullOrEmpty(orderField))
158             {
159                 throw new ArgumentNullException("orderField");
160             }
161             // 其他情况, 生成row_number分页查询语句
162             // SQL模版
163             const string format = @"select {0} from
164                                     (
165                                         select ROW_NUMBER() over(order by [{1}] {2}) as num, {0} from [{3}] {4}
166                                     )
167                                     as tbl
168                                     where
169                                         tbl.num between ({5}-1)*{6} + 1 and {5}*{6};";
170             // where语句组建
171             where = string.IsNullOrEmpty(where) ? string.Empty : "where " + where;
172             // 查询字段拼接
173             string column = columns != null && columns.Any() ? string.Join(" , ", columns) : "*";
174             return string.Format(format, column, orderField, isDesc ? "desc" : string.Empty, table, where, index, size);
175         }
176         #endregion
177         #region 生成查询数据库语句查询全部 +static string GenerateQuerySql(string table, string[] columns, string wheres, string orderField, bool isDesc = true)
178         /// <summary>
179         /// 生成查询数据库语句查询全部, 返回生成的T-SQL语句
180         /// </summary>
181         /// <param name="table">表名</param>
182         /// <param name="columns">列集合</param>
183         /// <param name="where">条件语句(忽略则传入null)</param>
184         /// <param name="orderField">排序字段(即根据那个字段排序)(忽略则传入null)</param>
185         /// <param name="isDesc">排序方式(0:降序(desc)|1:升序(asc))(忽略则传入-1)</param>
186         /// <returns>生成的T-SQL语句</returns>
187         public static string GenerateQuerySql(string table, string[] columns, string where, string orderField, bool isDesc = true)
188         {
189             // where语句组建
190             where = string.IsNullOrEmpty(where) ? string.Empty : "where " + where;
191             // 查询字段拼接
192             string column = columns != null && columns.Any() ? string.Join(" , ", columns) : "*";
193             const string format = "select {0} from [{1}] {2} {3} {4}";
194             return string.Format(format, column, table, where,
195                 string.IsNullOrEmpty(orderField) ? string.Empty : "order by " + orderField,
196                 isDesc && !string.IsNullOrEmpty(orderField) ? "desc" : string.Empty);
197         }
198         #endregion
199 
200         #region 生成分页查询数据库语句查询第一页 +static string GenerateQuerySql(string table, string[] columns, int size, string where, string orderField, bool isDesc = true)
201         /// <summary>
202         /// 生成分页查询数据库语句查询第一页, 返回生成的T-SQL语句
203         /// </summary>
204         /// <param name="table">表名</param>
205         /// <param name="columns">列集合</param>
206         /// <param name="size">显示页面大小(即显示条数)</param>
207         /// <param name="where">条件语句(忽略则传入null)</param>
208         /// <param name="orderField">排序字段(即根据那个字段排序)(忽略则传入null)</param>
209         /// <param name="isDesc">排序方式(0:降序(desc)|1:升序(asc))(忽略则传入-1)</param>
210         /// <returns>生成的T-SQL语句</returns>
211         public static string GenerateQuerySql(string table, string[] columns, int size, string where, string orderField, bool isDesc = true)
212         {
213             // where语句组建
214             where = string.IsNullOrEmpty(where) ? string.Empty : "where " + where;
215             // 查询字段拼接
216             string column = columns != null && columns.Any() ? string.Join(" , ", columns) : "*";
217             const string format = "select top {0} {1} from [{2}] {3} {4} {5}";
218             return string.Format(format, size, column, table, where,
219                   string.IsNullOrEmpty(orderField) ? string.Empty : "order by " + orderField,
220                   isDesc && !string.IsNullOrEmpty(orderField) ? "desc" : string.Empty);
221         }
222         #endregion
223         #endregion
224 
225         #region 将一个SqlDataReader对象转换成一个实体类对象 +static TEntity MapEntity<TEntity>(SqlDataReader reader) where TEntity : class,new()
226         /// <summary>
227         /// 将一个SqlDataReader对象转换成一个实体类对象
228         /// </summary>
229         /// <typeparam name="TEntity">实体类型</typeparam>
230         /// <param name="reader">当前指向的reader</param>
231         /// <returns>实体对象</returns>
232         public static TEntity MapEntity<TEntity>(SqlDataReader reader) where TEntity : class,new()
233         {
234             try
235             {
236                 // 获取所有属性
237                 var props = typeof(TEntity).GetProperties();
238                 // 创建返回实体
239                 var entity = new TEntity();
240                 foreach (var prop in props)
241                 {
242                     if (prop.CanWrite)
243                     {
244                         try
245                         {
246                             // 根据列名获取列在行中的序号
247                             var index = reader.GetOrdinal(prop.Name);
248                             // 根据序号获取当前值
249                             var data = reader.GetValue(index);
250                             if (data != DBNull.Value)
251                             {
252                                 prop.SetValue(entity, Convert.ChangeType(data, prop.PropertyType), null);
253                             }
254                         }
255                         catch (IndexOutOfRangeException)
256                         {
257                             continue;
258                         }
259                     }
260                 }
261                 return entity;
262             }
263             catch
264             {
265                 return null;
266             }
267         }
268         #endregion
269 
270         #endregion
271 
272         #region SQL执行方法
273 
274         #region ExecuteNonQuery +static int ExecuteNonQuery(string cmdText, params SqlParameter[] parameters)
275         /// <summary>
276         /// 执行一个非查询的T-SQL语句,返回受影响行数,如果执行的是非增、删、改操作,返回-1
277         /// </summary>
278         /// <param name="cmdText">要执行的T-SQL语句</param>
279         /// <param name="parameters">参数列表</param>
280         /// <exception cref="链接数据库异常"></exception>
281         /// <returns>受影响的行数</returns>
282         public static int ExecuteNonQuery(string cmdText, params SqlParameter[] parameters)
283         {
284             return ExecuteNonQuery(cmdText, CommandType.Text, parameters);
285         }
286         #endregion
287 
288         #region ExecuteNonQuery +static int ExecuteNonQuery(string cmdText, CommandType type, params SqlParameter[] parameters)
289         /// <summary>
290         /// 执行一个非查询的T-SQL语句,返回受影响行数,如果执行的是非增、删、改操作,返回-1
291         /// </summary>
292         /// <param name="cmdText">要执行的T-SQL语句</param>
293         /// <param name="type">命令类型</param>
294         /// <param name="parameters">参数列表</param>
295         /// <exception cref="链接数据库异常"></exception>
296         /// <returns>受影响的行数</returns>
297         public static int ExecuteNonQuery(string cmdText, CommandType type, params SqlParameter[] parameters)
298         {
299             using (SqlConnection conn = new SqlConnection(connStr))
300             {
301                 using (SqlCommand cmd = new SqlCommand(cmdText, conn))
302                 {
303                     if (parameters != null)
304                     {
305                         cmd.Parameters.Clear();
306                         cmd.Parameters.AddRange(parameters);
307                     }
308                     cmd.CommandType = type;
309                     try
310                     {
311                         conn.Open();
312                         int res = cmd.ExecuteNonQuery();
313                         cmd.Parameters.Clear();
314                         return res;
315                     }
316                     catch (System.Data.SqlClient.SqlException e)
317                     {
318                         conn.Close();
319                         throw e;
320                     }
321                 }
322             }
323         }
324         #endregion
325 
326         #region ExecuteScalar +static object ExecuteScalar(string cmdText, params SqlParameter[] parameters)
327         /// <summary>
328         /// 执行一个查询的T-SQL语句,返回第一行第一列的结果
329         /// </summary>
330         /// <param name="cmdText">要执行的T-SQL语句</param>
331         /// <param name="parameters">参数列表</param>
332         /// <exception cref="链接数据库异常"></exception>
333         /// <returns>返回第一行第一列的数据</returns>
334         public static object ExecuteScalar(string cmdText, params SqlParameter[] parameters)
335         {
336             return ExecuteScalar(cmdText, CommandType.Text, parameters);
337         }
338         #endregion
339 
340         #region ExecuteScalar +static object ExecuteScalar(string cmdText, CommandType type, params SqlParameter[] parameters)
341         /// <summary>
342         /// 执行一个查询的T-SQL语句,返回第一行第一列的结果
343         /// </summary>
344         /// <param name="cmdText">要执行的T-SQL语句</param>
345         /// <param name="type">命令类型</param>
346         /// <param name="parameters">参数列表</param>
347         /// <exception cref="链接数据库异常"></exception>
348         /// <returns>返回第一行第一列的数据</returns>
349         public static object ExecuteScalar(string cmdText, CommandType type, params SqlParameter[] parameters)
350         {
351             using (SqlConnection conn = new SqlConnection(connStr))
352             {
353                 using (SqlCommand cmd = new SqlCommand(cmdText, conn))
354                 {
355                     if (parameters != null)
356                     {
357                         cmd.Parameters.Clear();
358                         cmd.Parameters.AddRange(parameters);
359                     }
360                     cmd.CommandType = type;
361                     try
362                     {
363                         conn.Open();
364                         object res = cmd.ExecuteScalar();
365                         cmd.Parameters.Clear();
366                         return res;
367                     }
368                     catch (System.Data.SqlClient.SqlException e)
369                     {
370                         conn.Close();
371                         throw e;
372                     }
373                 }
374             }
375         }
376         #endregion
377 
378         #region ExecuteReader +static void ExecuteReader(string cmdText, Action<SqlDataReader> action, params SqlParameter[] parameters)
379         /// <summary>
380         /// 利用委托 执行一个大数据查询的T-SQL语句
381         /// </summary>
382         /// <param name="cmdText">要执行的T-SQL语句</param>
383         /// <param name="action">传入执行的委托对象</param>
384         /// <param name="parameters">参数列表</param>
385         /// <exception cref="链接数据库异常"></exception>
386         public static void ExecuteReader(string cmdText, Action<SqlDataReader> action, params SqlParameter[] parameters)
387         {
388             ExecuteReader(cmdText, action, CommandType.Text, parameters);
389         }
390         #endregion
391 
392         #region ExecuteReader +static void ExecuteReader(string cmdText, Action<SqlDataReader> action, CommandType type, params SqlParameter[] parameters)
393         /// <summary>
394         /// 利用委托 执行一个大数据查询的T-SQL语句
395         /// </summary>
396         /// <param name="cmdText">要执行的T-SQL语句</param>
397         /// <param name="action">传入执行的委托对象</param>
398         /// <param name="type">命令类型</param>
399         /// <param name="parameters">参数列表</param>
400         /// <exception cref="链接数据库异常"></exception>
401         public static void ExecuteReader(string cmdText, Action<SqlDataReader> action, CommandType type, params SqlParameter[] parameters)
402         {
403             using (SqlConnection conn = new SqlConnection(connStr))
404             {
405                 using (SqlCommand cmd = new SqlCommand(cmdText, conn))
406                 {
407                     if (parameters != null)
408                     {
409                         cmd.Parameters.Clear();
410                         cmd.Parameters.AddRange(parameters);
411                     }
412                     cmd.CommandType = type;
413                     try
414                     {
415                         conn.Open();
416                         using (SqlDataReader reader = cmd.ExecuteReader())
417                         {
418                             action(reader);
419                         }
420                         cmd.Parameters.Clear();
421                     }
422                     catch (System.Data.SqlClient.SqlException e)
423                     {
424                         conn.Close();
425                         throw e;
426                     }
427                 }
428             }
429         }
430         #endregion
431 
432         #region ExecuteReader +static SqlDataReader ExecuteReader(string cmdText, params SqlParameter[] parameters)
433         /// <summary>
434         /// 执行一个查询的T-SQL语句, 返回一个SqlDataReader对象, 如果出现SQL语句执行错误, 将会关闭连接通道抛出异常
435         ///  ( 注意:调用该方法后,一定要对SqlDataReader进行Close )
436         /// </summary>
437         /// <param name="cmdText">要执行的T-SQL语句</param>
438         /// <param name="parameters">参数列表</param>
439         /// <exception cref="链接数据库异常"></exception>
440         /// <returns>SqlDataReader对象</returns>
441         public static SqlDataReader ExecuteReader(string cmdText, params SqlParameter[] parameters)
442         {
443             return ExecuteReader(cmdText, CommandType.Text, parameters);
444         }
445         #endregion
446 
447         #region ExecuteReader +static SqlDataReader ExecuteReader(string cmdText, CommandType type, params SqlParameter[] parameters)
448         /// <summary>
449         /// 执行一个查询的T-SQL语句, 返回一个SqlDataReader对象, 如果出现SQL语句执行错误, 将会关闭连接通道抛出异常
450         ///  ( 注意:调用该方法后,一定要对SqlDataReader进行Close )
451         /// </summary>
452         /// <param name="cmdText">要执行的T-SQL语句</param>
453         /// <param name="type">命令类型</param>
454         /// <param name="parameters">参数列表</param>
455         /// <exception cref="链接数据库异常"></exception>
456         /// <returns>SqlDataReader对象</returns>
457         public static SqlDataReader ExecuteReader(string cmdText, CommandType type, params SqlParameter[] parameters)
458         {
459             SqlConnection conn = new SqlConnection(connStr);
460             using (SqlCommand cmd = new SqlCommand(cmdText, conn))
461             {
462                 if (parameters != null)
463                 {
464                     cmd.Parameters.Clear();
465                     cmd.Parameters.AddRange(parameters);
466                 }
467                 cmd.CommandType = type;
468                 conn.Open();
469                 try
470                 {
471                     SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
472                     cmd.Parameters.Clear();
473                     return reader;
474                 }
475                 catch (System.Data.SqlClient.SqlException ex)
476                 {
477                     //出现异常关闭连接并且释放
478                     conn.Close();
479                     throw ex;
480                 }
481             }
482         }
483         #endregion
484 
485         #region ExecuteDataSet +static DataSet ExecuteDataSet(string cmdText, params SqlParameter[] parameters)
486         /// <summary>
487         /// 执行一个查询的T-SQL语句, 返回一个离线数据集DataSet
488         /// </summary>
489         /// <param name="cmdText">要执行的T-SQL语句</param>
490         /// <param name="parameters">参数列表</param>
491         /// <returns>离线数据集DataSet</returns>
492         public static DataSet ExecuteDataSet(string cmdText, params SqlParameter[] parameters)
493         {
494             return ExecuteDataSet(cmdText, CommandType.Text, parameters);
495         }
496         #endregion
497 
498         #region ExecuteDataSet +static DataSet ExecuteDataSet(string cmdText, CommandType type, params SqlParameter[] parameters)
499         /// <summary>
500         /// 执行一个查询的T-SQL语句, 返回一个离线数据集DataSet
501         /// </summary>
502         /// <param name="cmdText">要执行的T-SQL语句</param>
503         /// <param name="type">命令类型</param>
504         /// <param name="parameters">参数列表</param>
505         /// <returns>离线数据集DataSet</returns>
506         public static DataSet ExecuteDataSet(string cmdText, CommandType type, params SqlParameter[] parameters)
507         {
508             using (SqlDataAdapter adapter = new SqlDataAdapter(cmdText, connStr))
509             {
510                 using (DataSet ds = new DataSet())
511                 {
512                     if (parameters != null)
513                     {
514                         adapter.SelectCommand.Parameters.Clear();
515                         adapter.SelectCommand.Parameters.AddRange(parameters);
516                     }
517                     adapter.SelectCommand.CommandType = type;
518                     adapter.Fill(ds);
519                     adapter.SelectCommand.Parameters.Clear();
520                     return ds;
521                 }
522             }
523         }
524         #endregion
525 
526         #region ExecuteDataTable +static DataTable ExecuteDataTable(string cmdText, params SqlParameter[] parameters)
527         /// <summary>
528         /// 执行一个数据表查询的T-SQL语句, 返回一个DataTable
529         /// </summary>
530         /// <param name="cmdText">要执行的T-SQL语句</param>
531         /// <param name="parameters">参数列表</param>
532         /// <returns>查询到的数据表</returns>
533         public static DataTable ExecuteDataTable(string cmdText, params SqlParameter[] parameters)
534         {
535             return ExecuteDataTable(cmdText, CommandType.Text, parameters);
536         }
537         #endregion
538 
539         #region ExecuteDataTable +static DataTable ExecuteDataTable(string cmdText, CommandType type, params SqlParameter[] parameters)
540         /// <summary>
541         /// 执行一个数据表查询的T-SQL语句, 返回一个DataTable
542         /// </summary>
543         /// <param name="cmdText">要执行的T-SQL语句</param>
544         /// <param name="type">命令类型</param>
545         /// <param name="parameters">参数列表</param>
546         /// <returns>查询到的数据表</returns>
547         public static DataTable ExecuteDataTable(string cmdText, CommandType type, params SqlParameter[] parameters)
548         {
549             return ExecuteDataSet(cmdText, type, parameters).Tables[0];
550         }
551         #endregion
552         #endregion
553     }
554 }
View Code
   1 using System;
   2 using System.Collections;
   3 using System.Collections.Generic;
   4 using System.Configuration;
   5 using System.Data;
   6 using System.Data.SqlClient;
   7 using System.Linq;
   8 using System.Text;
   9 using System.Xml;
  10 
  11 namespace DAL
  12 {
  13     public sealed class SqlHelper
  14     { 
  15         #region 私有构造函数和方法
  16 
  17         private SqlHelper() { }
  18 
  19         /// <summary> 
  20         /// 将SqlParameter参数数组(参数值)分配给SqlCommand命令. 
  21         /// 这个方法将给任何一个参数分配DBNull.Value; 
  22         /// 该操作将阻止默认值的使用. 
  23         /// </summary> 
  24         /// <param name="command">命令名</param> 
  25         /// <param name="commandParameters">SqlParameters数组</param> 
  26         private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters)
  27         {
  28             if (command == null) throw new ArgumentNullException("command");
  29             if (commandParameters != null)
  30             {
  31                 foreach (SqlParameter p in commandParameters)
  32                 {
  33                     if (p != null)
  34                     {
  35                         // 检查未分配值的输出参数,将其分配以DBNull.Value. 
  36                         if ((p.Direction == ParameterDirection.InputOutput || p.Direction == ParameterDirection.Input) &&
  37                             (p.Value == null))
  38                         {
  39                             p.Value = DBNull.Value;
  40                         }
  41                         command.Parameters.Add(p);
  42                     }
  43                 }
  44             }
  45         }
  46 
  47         /// <summary> 
  48         /// 将DataRow类型的列值分配到SqlParameter参数数组. 
  49         /// </summary> 
  50         /// <param name="commandParameters">要分配值的SqlParameter参数数组</param> 
  51         /// <param name="dataRow">将要分配给存储过程参数的DataRow</param> 
  52         private static void AssignParameterValues(SqlParameter[] commandParameters, DataRow dataRow)
  53         {
  54             if ((commandParameters == null) || (dataRow == null))
  55             {
  56                 return;
  57             }
  58 
  59             int i = 0;
  60             // 设置参数值 
  61             foreach (SqlParameter commandParameter in commandParameters)
  62             {
  63                 // 创建参数名称,如果不存在,只抛出一个异常. 
  64                 if (commandParameter.ParameterName == null ||
  65                     commandParameter.ParameterName.Length <= 1)
  66                     throw new Exception(
  67                         string.Format("请提供参数{0}一个有效的名称{1}.", i, commandParameter.ParameterName));
  68                 // 从dataRow的表中获取为参数数组中数组名称的列的索引. 
  69                 // 如果存在和参数名称相同的列,则将列值赋给当前名称的参数. 
  70                 if (dataRow.Table.Columns.IndexOf(commandParameter.ParameterName.Substring(1)) != -1)
  71                     commandParameter.Value = dataRow[commandParameter.ParameterName.Substring(1)];
  72                 i++;
  73             }
  74         }
  75 
  76         /// <summary> 
  77         /// 将一个对象数组分配给SqlParameter参数数组. 
  78         /// </summary> 
  79         /// <param name="commandParameters">要分配值的SqlParameter参数数组</param> 
  80         /// <param name="parameterValues">将要分配给存储过程参数的对象数组</param> 
  81         private static void AssignParameterValues(SqlParameter[] commandParameters, object[] parameterValues)
  82         {
  83             if ((commandParameters == null) || (parameterValues == null))
  84             {
  85                 return;
  86             }
  87 
  88             // 确保对象数组个数与参数个数匹配,如果不匹配,抛出一个异常. 
  89             if (commandParameters.Length != parameterValues.Length)
  90             {
  91                 throw new ArgumentException("参数值个数与参数不匹配.");
  92             }
  93 
  94             // 给参数赋值 
  95             for (int i = 0, j = commandParameters.Length; i < j; i++)
  96             {
  97                 // If the current array value derives from IDbDataParameter, then assign its Value property 
  98                 if (parameterValues[i] is IDbDataParameter)
  99                 {
 100                     IDbDataParameter paramInstance = (IDbDataParameter)parameterValues[i];
 101                     if (paramInstance.Value == null)
 102                     {
 103                         commandParameters[i].Value = DBNull.Value;
 104                     }
 105                     else
 106                     {
 107                         commandParameters[i].Value = paramInstance.Value;
 108                     }
 109                 }
 110                 else if (parameterValues[i] == null)
 111                 {
 112                     commandParameters[i].Value = DBNull.Value;
 113                 }
 114                 else
 115                 {
 116                     commandParameters[i].Value = parameterValues[i];
 117                 }
 118             }
 119         }
 120 
 121         /// <summary> 
 122         /// 预处理用户提供的命令,数据库连接/事务/命令类型/参数 
 123         /// </summary> 
 124         /// <param name="command">要处理的SqlCommand</param> 
 125         /// <param name="connection">数据库连接</param> 
 126         /// <param name="transaction">一个有效的事务或者是null值</param> 
 127         /// <param name="commandType">命令类型 (存储过程,命令文本, 其它.)</param> 
 128         /// <param name="commandText">存储过程名或都T-SQL命令文本</param> 
 129         /// <param name="commandParameters">和命令相关联的SqlParameter参数数组,如果没有参数为'null'</param> 
 130         /// <param name="mustCloseConnection"><c>true</c> 如果连接是打开的,则为true,其它情况下为false.</param> 
 131         private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, out bool mustCloseConnection)
 132         {
 133             if (command == null) throw new ArgumentNullException("command");
 134             if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");
 135 
 136             // If the provided connection is not open, we will open it 
 137             if (connection.State != ConnectionState.Open)
 138             {
 139                 mustCloseConnection = true;
 140                 connection.Open();
 141             }
 142             else
 143             {
 144                 mustCloseConnection = false;
 145             }
 146 
 147             // 给命令分配一个数据库连接. 
 148             command.Connection = connection;
 149 
 150             // 设置命令文本(存储过程名或SQL语句) 
 151             command.CommandText = commandText;
 152 
 153             // 分配事务 
 154             if (transaction != null)
 155             {
 156                 if (transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
 157                 command.Transaction = transaction;
 158             }
 159 
 160             // 设置命令类型. 
 161             command.CommandType = commandType;
 162 
 163             // 分配命令参数 
 164             if (commandParameters != null)
 165             {
 166                 AttachParameters(command, commandParameters);
 167             }
 168             return;
 169         }
 170 
 171         #endregion 私有构造函数和方法结束
 172 
 173         #region 数据库连接
 174         /// <summary> 
 175         /// 一个有效的数据库连接字符串 
 176         /// </summary> 
 177         /// <returns></returns> 
 178         public static string GetConnSting()
 179         {
 180             return ConfigurationManager.AppSettings["ConStr"];
 181         }
 182         /// <summary> 
 183         /// 一个有效的数据库连接对象 
 184         /// </summary> 
 185         /// <returns></returns> 
 186         public static SqlConnection GetConnection()
 187         {
 188             SqlConnection Connection = new SqlConnection(SqlHelper.GetConnSting());
 189             return Connection;
 190         }
 191         #endregion
 192         #region 公用方法
 193         /// <summary>
 194         /// 判断是否存在某表的某个字段
 195         /// </summary>
 196         /// <param name="tableName">表名称</param>
 197         /// <param name="columnName">列名称</param>
 198         /// <returns>是否存在</returns>
 199         public static bool ColumnExists(string tableName, string columnName)
 200         {
 201             string sql = "select count(1) from syscolumns where [id]=object_id('" + tableName + "') and [name]='" + columnName + "'";
 202             object res = GetSingle(sql);
 203             if (res == null)
 204             {
 205                 return false;
 206             }
 207             return Convert.ToInt32(res) > 0;
 208         }
 209         public static int GetMaxID(string FieldName, string TableName)
 210         {
 211             string strsql = "select max(" + FieldName + ")+1 from " + TableName;
 212             object obj = GetSingle(strsql);
 213             if (obj == null)
 214             {
 215                 return 1;
 216             }
 217             else
 218             {
 219                 return int.Parse(obj.ToString());
 220             }
 221         }
 222         public static bool Exists(string strSql)
 223         {
 224             object obj = GetSingle(strSql);
 225             int cmdresult;
 226             if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
 227             {
 228                 cmdresult = 0;
 229             }
 230             else
 231             {
 232                 cmdresult = int.Parse(obj.ToString());
 233             }
 234             if (cmdresult == 0)
 235             {
 236                 return false;
 237             }
 238             else
 239             {
 240                 return true;
 241             }
 242         }
 243         public static bool Exists(string strSql, params SqlParameter[] cmdParms)
 244         {
 245             object obj = GetSingle(GetConnSting(), CommandType.Text, strSql, cmdParms);
 246             int cmdresult;
 247             if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
 248             {
 249                 cmdresult = 0;
 250             }
 251             else
 252             {
 253                 cmdresult = int.Parse(obj.ToString());
 254             }
 255             if (cmdresult == 0)
 256             {
 257                 return false;
 258             }
 259             else
 260             {
 261                 return true;
 262             }
 263         }
 264         /// <summary>
 265         /// 执行一条计算查询结果语句,返回查询结果(object)。
 266         /// </summary>
 267         /// <param name="SQLString">计算查询结果语句</param>
 268         /// <returns>查询结果(object)</returns>
 269         public static object GetSingle(string SQLString)
 270         {
 271             using (SqlConnection connection = new SqlConnection(GetConnSting()))
 272             {
 273                 using (SqlCommand cmd = new SqlCommand(SQLString, connection))
 274                 {
 275                     try
 276                     {
 277                         connection.Open();
 278                         object obj = cmd.ExecuteScalar();
 279                         if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
 280                         {
 281                             return null;
 282                         }
 283                         else
 284                         {
 285                             return obj;
 286                         }
 287                     }
 288                     catch (System.Data.SqlClient.SqlException e)
 289                     {
 290                         connection.Close();
 291                         throw e;
 292                     }
 293                 }
 294             }
 295         }
 296         /// <summary>
 297         /// 执行一条计算查询结果语句,返回查询结果(object)。
 298         /// </summary>
 299         /// <param name="SQLString">计算查询结果语句</param>
 300         /// <returns>查询结果(object)</returns>
 301         public static object GetSingle(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 302         {
 303             return ExecuteScalar(connectionString, commandType, commandText, commandParameters);
 304         }
 305         #endregion
 306         #region ExecuteNonQuery命令
 307 
 308         /// <summary> 
 309         /// 执行指定连接字符串,类型的SqlCommand. 
 310         /// </summary> 
 311         /// <remarks> 
 312         /// 示例:  
 313         ///  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders"); 
 314         /// </remarks> 
 315         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
 316         /// <param name="commandType">命令类型 (存储过程,命令文本, 其它.)</param> 
 317         /// <param name="commandText">存储过程名称或SQL语句</param> 
 318         /// <returns>返回命令影响的行数</returns> 
 319         public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText)
 320         {
 321             return ExecuteNonQuery(connectionString, commandType, commandText, (SqlParameter[])null);
 322         }
 323 
 324         /// <summary> 
 325         /// 执行指定连接字符串,类型的SqlCommand.如果没有提供参数,不返回结果. 
 326         /// </summary> 
 327         /// <remarks> 
 328         /// 示例:  
 329         ///  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24)); 
 330         /// </remarks> 
 331         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
 332         /// <param name="commandType">命令类型 (存储过程,命令文本, 其它.)</param> 
 333         /// <param name="commandText">存储过程名称或SQL语句</param> 
 334         /// <param name="commandParameters">SqlParameter参数数组</param> 
 335         /// <returns>返回命令影响的行数</returns> 
 336         public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 337         {
 338             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
 339 
 340             using (SqlConnection connection = new SqlConnection(connectionString))
 341             {
 342                 connection.Open();
 343 
 344                 return ExecuteNonQuery(connection, commandType, commandText, commandParameters);
 345             }
 346         }
 347 
 348         /// <summary> 
 349         /// 执行指定连接字符串的存储过程,将对象数组的值赋给存储过程参数, 
 350         /// 此方法需要在参数缓存方法中探索参数并生成参数. 
 351         /// </summary> 
 352         /// <remarks> 
 353         /// 这个方法没有提供访问输出参数和返回值. 
 354         /// 示例:  
 355         ///  int result = ExecuteNonQuery(connString, "PublishOrders", 24, 36); 
 356         /// </remarks> 
 357         /// <param name="connectionString">一个有效的数据库连接字符串/param> 
 358         /// <param name="spName">存储过程名称</param> 
 359         /// <param name="parameterValues">分配到存储过程输入参数的对象数组</param> 
 360         /// <returns>返回受影响的行数</returns> 
 361         public static int ExecuteNonQuery(string connectionString, string spName, params object[] parameterValues)
 362         {
 363             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
 364             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
 365 
 366             // 如果存在参数值 
 367             if ((parameterValues != null) && (parameterValues.Length > 0))
 368             {
 369                 // 从探索存储过程参数(加载到缓存)并分配给存储过程参数数组. 
 370                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
 371 
 372                 // 给存储过程参数赋值 
 373                 AssignParameterValues(commandParameters, parameterValues);
 374 
 375                 return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters);
 376             }
 377             else
 378             {
 379                 // 没有参数情况下 
 380                 return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName);
 381             }
 382         }
 383 
 384         /// <summary> 
 385         /// 执行指定数据库连接对象的命令 
 386         /// </summary> 
 387         /// <remarks> 
 388         /// 示例:  
 389         ///  int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders"); 
 390         /// </remarks> 
 391         /// <param name="connection">一个有效的数据库连接对象</param> 
 392         /// <param name="commandType">命令类型(存储过程,命令文本或其它.)</param> 
 393         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
 394         /// <returns>返回影响的行数</returns> 
 395         public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText)
 396         {
 397             return ExecuteNonQuery(connection, commandType, commandText, (SqlParameter[])null);
 398         }
 399 
 400         /// <summary> 
 401         /// 执行指定数据库连接对象的命令 
 402         /// </summary> 
 403         /// <remarks> 
 404         /// 示例:  
 405         ///  int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24)); 
 406         /// </remarks> 
 407         /// <param name="connection">一个有效的数据库连接对象</param> 
 408         /// <param name="commandType">命令类型(存储过程,命令文本或其它.)</param> 
 409         /// <param name="commandText">T存储过程名称或T-SQL语句</param> 
 410         /// <param name="commandParameters">SqlParamter参数数组</param> 
 411         /// <returns>返回影响的行数</returns> 
 412         public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 413         {
 414             if (connection == null) throw new ArgumentNullException("connection");
 415 
 416             // 创建SqlCommand命令,并进行预处理 
 417             SqlCommand cmd = new SqlCommand();
 418             bool mustCloseConnection = false;
 419             PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);
 420 
 421             // Finally, execute the command 
 422             int retval = cmd.ExecuteNonQuery();
 423 
 424             // 清除参数,以便再次使用. 
 425             cmd.Parameters.Clear();
 426             if (mustCloseConnection)
 427                 connection.Close();
 428             return retval;
 429         }
 430 
 431         /// <summary> 
 432         /// 执行指定数据库连接对象的命令,将对象数组的值赋给存储过程参数. 
 433         /// </summary> 
 434         /// <remarks> 
 435         /// 此方法不提供访问存储过程输出参数和返回值 
 436         /// 示例:  
 437         ///  int result = ExecuteNonQuery(conn, "PublishOrders", 24, 36); 
 438         /// </remarks> 
 439         /// <param name="connection">一个有效的数据库连接对象</param> 
 440         /// <param name="spName">存储过程名</param> 
 441         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
 442         /// <returns>返回影响的行数</returns> 
 443         public static int ExecuteNonQuery(SqlConnection connection, string spName, params object[] parameterValues)
 444         {
 445             if (connection == null) throw new ArgumentNullException("connection");
 446             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
 447 
 448             // 如果有参数值 
 449             if ((parameterValues != null) && (parameterValues.Length > 0))
 450             {
 451                 // 从缓存中加载存储过程参数 
 452                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
 453 
 454                 // 给存储过程分配参数值 
 455                 AssignParameterValues(commandParameters, parameterValues);
 456 
 457                 return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName, commandParameters);
 458             }
 459             else
 460             {
 461                 return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName);
 462             }
 463         }
 464 
 465         /// <summary> 
 466         /// 执行带事务的SqlCommand. 
 467         /// </summary> 
 468         /// <remarks> 
 469         /// 示例.:  
 470         ///  int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "PublishOrders"); 
 471         /// </remarks> 
 472         /// <param name="transaction">一个有效的数据库连接对象</param> 
 473         /// <param name="commandType">命令类型(存储过程,命令文本或其它.)</param> 
 474         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
 475         /// <returns>返回影响的行数/returns> 
 476         public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText)
 477         {
 478             return ExecuteNonQuery(transaction, commandType, commandText, (SqlParameter[])null);
 479         }
 480 
 481         /// <summary> 
 482         /// 执行带事务的SqlCommand(指定参数). 
 483         /// </summary> 
 484         /// <remarks> 
 485         /// 示例:  
 486         ///  int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); 
 487         /// </remarks> 
 488         /// <param name="transaction">一个有效的数据库连接对象</param> 
 489         /// <param name="commandType">命令类型(存储过程,命令文本或其它.)</param> 
 490         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
 491         /// <param name="commandParameters">SqlParamter参数数组</param> 
 492         /// <returns>返回影响的行数</returns> 
 493         public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 494         {
 495             if (transaction == null) throw new ArgumentNullException("transaction");
 496             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
 497 
 498             // 预处理 
 499             SqlCommand cmd = new SqlCommand();
 500             bool mustCloseConnection = false;
 501             PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
 502 
 503             // 执行 
 504             int retval = cmd.ExecuteNonQuery();
 505 
 506             // 清除参数集,以便再次使用. 
 507             cmd.Parameters.Clear();
 508             return retval;
 509         }
 510 
 511         /// <summary> 
 512         /// 执行带事务的SqlCommand(指定参数值). 
 513         /// </summary> 
 514         /// <remarks> 
 515         /// 此方法不提供访问存储过程输出参数和返回值 
 516         /// 示例:  
 517         ///  int result = ExecuteNonQuery(conn, trans, "PublishOrders", 24, 36); 
 518         /// </remarks> 
 519         /// <param name="transaction">一个有效的数据库连接对象</param> 
 520         /// <param name="spName">存储过程名</param> 
 521         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
 522         /// <returns>返回受影响的行数</returns> 
 523         public static int ExecuteNonQuery(SqlTransaction transaction, string spName, params object[] parameterValues)
 524         {
 525             if (transaction == null) throw new ArgumentNullException("transaction");
 526             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
 527             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
 528 
 529             // 如果有参数值 
 530             if ((parameterValues != null) && (parameterValues.Length > 0))
 531             {
 532                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
 533                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
 534 
 535                 // 给存储过程参数赋值 
 536                 AssignParameterValues(commandParameters, parameterValues);
 537 
 538                 // 调用重载方法 
 539                 return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName, commandParameters);
 540             }
 541             else
 542             {
 543                 // 没有参数值 
 544                 return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName);
 545             }
 546         }
 547 
 548         #endregion ExecuteNonQuery方法结束
 549 
 550         #region ExecuteDataset方法
 551 
 552         /// <summary> 
 553         /// 执行指定数据库连接字符串的命令,返回DataSet. 
 554         /// </summary> 
 555         /// <remarks> 
 556         /// 示例:  
 557         ///  DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders"); 
 558         /// </remarks> 
 559         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
 560         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
 561         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
 562         /// <returns>返回一个包含结果集的DataSet</returns> 
 563         public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText)
 564         {
 565             return ExecuteDataset(connectionString, commandType, commandText, (SqlParameter[])null);
 566         }
 567 
 568         /// <summary> 
 569         /// 执行指定数据库连接字符串的命令,返回DataSet. 
 570         /// </summary> 
 571         /// <remarks> 
 572         /// 示例: 
 573         ///  DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); 
 574         /// </remarks> 
 575         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
 576         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
 577         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
 578         /// <param name="commandParameters">SqlParamters参数数组</param> 
 579         /// <returns>返回一个包含结果集的DataSet</returns> 
 580         public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 581         {
 582             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
 583 
 584             // 创建并打开数据库连接对象,操作完成释放对象. 
 585             using (SqlConnection connection = new SqlConnection(connectionString))
 586             {
 587                 connection.Open();
 588 
 589                 // 调用指定数据库连接字符串重载方法. 
 590                 return ExecuteDataset(connection, commandType, commandText, commandParameters);
 591             }
 592         }
 593 
 594         /// <summary> 
 595         /// 执行指定数据库连接字符串的命令,直接提供参数值,返回DataSet. 
 596         /// </summary> 
 597         /// <remarks> 
 598         /// 此方法不提供访问存储过程输出参数和返回值. 
 599         /// 示例: 
 600         ///  DataSet ds = ExecuteDataset(connString, "GetOrders", 24, 36); 
 601         /// </remarks> 
 602         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
 603         /// <param name="spName">存储过程名</param> 
 604         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
 605         /// <returns>返回一个包含结果集的DataSet</returns> 
 606         public static DataSet ExecuteDataset(string connectionString, string spName, params object[] parameterValues)
 607         {
 608             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
 609             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
 610 
 611             if ((parameterValues != null) && (parameterValues.Length > 0))
 612             {
 613                 // 从缓存中检索存储过程参数 
 614                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
 615 
 616                 // 给存储过程参数分配值 
 617                 AssignParameterValues(commandParameters, parameterValues);
 618 
 619                 return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName, commandParameters);
 620             }
 621             else
 622             {
 623                 return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName);
 624             }
 625         }
 626 
 627         /// <summary> 
 628         /// 执行指定数据库连接对象的命令,返回DataSet. 
 629         /// </summary> 
 630         /// <remarks> 
 631         /// 示例:  
 632         ///  DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders"); 
 633         /// </remarks> 
 634         /// <param name="connection">一个有效的数据库连接对象</param> 
 635         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
 636         /// <param name="commandText">存储过程名或T-SQL语句</param> 
 637         /// <returns>返回一个包含结果集的DataSet</returns> 
 638         public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText)
 639         {
 640             return ExecuteDataset(connection, commandType, commandText, (SqlParameter[])null);
 641         }
 642 
 643         /// <summary> 
 644         /// 执行指定数据库连接对象的命令,指定存储过程参数,返回DataSet. 
 645         /// </summary> 
 646         /// <remarks> 
 647         /// 示例:  
 648         ///  DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); 
 649         /// </remarks> 
 650         /// <param name="connection">一个有效的数据库连接对象</param> 
 651         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
 652         /// <param name="commandText">存储过程名或T-SQL语句</param> 
 653         /// <param name="commandParameters">SqlParamter参数数组</param> 
 654         /// <returns>返回一个包含结果集的DataSet</returns> 
 655         public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 656         {
 657             if (connection == null) throw new ArgumentNullException("connection");
 658 
 659             // 预处理 
 660             SqlCommand cmd = new SqlCommand();
 661             bool mustCloseConnection = false;
 662             PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);
 663 
 664             // 创建SqlDataAdapter和DataSet. 
 665             using (SqlDataAdapter da = new SqlDataAdapter(cmd))
 666             {
 667                 DataSet ds = new DataSet();
 668 
 669                 // 填充DataSet. 
 670                 da.Fill(ds);
 671 
 672                 cmd.Parameters.Clear();
 673 
 674                 if (mustCloseConnection)
 675                     connection.Close();
 676 
 677                 return ds;
 678             }
 679         }
 680 
 681         /// <summary> 
 682         /// 执行指定数据库连接对象的命令,指定参数值,返回DataSet. 
 683         /// </summary> 
 684         /// <remarks> 
 685         /// 此方法不提供访问存储过程输入参数和返回值. 
 686         /// 示例.:  
 687         ///  DataSet ds = ExecuteDataset(conn, "GetOrders", 24, 36); 
 688         /// </remarks> 
 689         /// <param name="connection">一个有效的数据库连接对象</param> 
 690         /// <param name="spName">存储过程名</param> 
 691         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
 692         /// <returns>返回一个包含结果集的DataSet</returns> 
 693         public static DataSet ExecuteDataset(SqlConnection connection, string spName, params object[] parameterValues)
 694         {
 695             if (connection == null) throw new ArgumentNullException("connection");
 696             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
 697 
 698             if ((parameterValues != null) && (parameterValues.Length > 0))
 699             {
 700                 // 比缓存中加载存储过程参数 
 701                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
 702 
 703                 // 给存储过程参数分配值 
 704                 AssignParameterValues(commandParameters, parameterValues);
 705 
 706                 return ExecuteDataset(connection, CommandType.StoredProcedure, spName, commandParameters);
 707             }
 708             else
 709             {
 710                 return ExecuteDataset(connection, CommandType.StoredProcedure, spName);
 711             }
 712         }
 713 
 714         /// <summary> 
 715         /// 执行指定事务的命令,返回DataSet. 
 716         /// </summary> 
 717         /// <remarks> 
 718         /// 示例:  
 719         ///  DataSet ds = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders"); 
 720         /// </remarks> 
 721         /// <param name="transaction">事务</param> 
 722         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
 723         /// <param name="commandText">存储过程名或T-SQL语句</param> 
 724         /// <returns>返回一个包含结果集的DataSet</returns> 
 725         public static DataSet ExecuteDataset(SqlTransaction transaction, CommandType commandType, string commandText)
 726         {
 727             return ExecuteDataset(transaction, commandType, commandText, (SqlParameter[])null);
 728         }
 729 
 730         /// <summary> 
 731         /// 执行指定事务的命令,指定参数,返回DataSet. 
 732         /// </summary> 
 733         /// <remarks> 
 734         /// 示例:  
 735         ///  DataSet ds = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); 
 736         /// </remarks> 
 737         /// <param name="transaction">事务</param> 
 738         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
 739         /// <param name="commandText">存储过程名或T-SQL语句</param> 
 740         /// <param name="commandParameters">SqlParamter参数数组</param> 
 741         /// <returns>返回一个包含结果集的DataSet</returns> 
 742         public static DataSet ExecuteDataset(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 743         {
 744             if (transaction == null) throw new ArgumentNullException("transaction");
 745             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
 746 
 747             // 预处理 
 748             SqlCommand cmd = new SqlCommand();
 749             bool mustCloseConnection = false;
 750             PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
 751 
 752             // 创建 DataAdapter & DataSet 
 753             using (SqlDataAdapter da = new SqlDataAdapter(cmd))
 754             {
 755                 DataSet ds = new DataSet();
 756                 da.Fill(ds);
 757                 cmd.Parameters.Clear();
 758                 return ds;
 759             }
 760         }
 761 
 762         /// <summary> 
 763         /// 执行指定事务的命令,指定参数值,返回DataSet. 
 764         /// </summary> 
 765         /// <remarks> 
 766         /// 此方法不提供访问存储过程输入参数和返回值. 
 767         /// 示例.:  
 768         ///  DataSet ds = ExecuteDataset(trans, "GetOrders", 24, 36); 
 769         /// </remarks> 
 770         /// <param name="transaction">事务</param> 
 771         /// <param name="spName">存储过程名</param> 
 772         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
 773         /// <returns>返回一个包含结果集的DataSet</returns> 
 774         public static DataSet ExecuteDataset(SqlTransaction transaction, string spName, params object[] parameterValues)
 775         {
 776             if (transaction == null) throw new ArgumentNullException("transaction");
 777             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
 778             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
 779 
 780             if ((parameterValues != null) && (parameterValues.Length > 0))
 781             {
 782                 // 从缓存中加载存储过程参数 
 783                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
 784 
 785                 // 给存储过程参数分配值 
 786                 AssignParameterValues(commandParameters, parameterValues);
 787 
 788                 return ExecuteDataset(transaction, CommandType.StoredProcedure, spName, commandParameters);
 789             }
 790             else
 791             {
 792                 return ExecuteDataset(transaction, CommandType.StoredProcedure, spName);
 793             }
 794         }
 795 
 796         #endregion ExecuteDataset数据集命令结束
 797 
 798         #region ExecuteReader 数据阅读器
 799 
 800         /// <summary> 
 801         /// 枚举,标识数据库连接是由SqlHelper提供还是由调用者提供 
 802         /// </summary> 
 803         private enum SqlConnectionOwnership
 804         {
 805             /// <summary>由SqlHelper提供连接</summary> 
 806             Internal,
 807             /// <summary>由调用者提供连接</summary> 
 808             External
 809         }
 810 
 811         /// <summary> 
 812         /// 执行指定数据库连接对象的数据阅读器. 
 813         /// </summary> 
 814         /// <remarks> 
 815         /// 如果是SqlHelper打开连接,当连接关闭DataReader也将关闭. 
 816         /// 如果是调用都打开连接,DataReader由调用都管理. 
 817         /// </remarks> 
 818         /// <param name="connection">一个有效的数据库连接对象</param> 
 819         /// <param name="transaction">一个有效的事务,或者为 'null'</param> 
 820         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
 821         /// <param name="commandText">存储过程名或T-SQL语句</param> 
 822         /// <param name="commandParameters">SqlParameters参数数组,如果没有参数则为'null'</param> 
 823         /// <param name="connectionOwnership">标识数据库连接对象是由调用者提供还是由SqlHelper提供</param> 
 824         /// <returns>返回包含结果集的SqlDataReader</returns> 
 825         private static SqlDataReader ExecuteReader(SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, SqlConnectionOwnership connectionOwnership)
 826         {
 827             if (connection == null) throw new ArgumentNullException("connection");
 828 
 829             bool mustCloseConnection = false;
 830             // 创建命令 
 831             SqlCommand cmd = new SqlCommand();
 832             try
 833             {
 834                 PrepareCommand(cmd, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
 835 
 836                 // 创建数据阅读器 
 837                 SqlDataReader dataReader;
 838 
 839                 if (connectionOwnership == SqlConnectionOwnership.External)
 840                 {
 841                     dataReader = cmd.ExecuteReader();
 842                 }
 843                 else
 844                 {
 845                     dataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
 846                 }
 847 
 848                 //清除参数 以便再次使用
 849                 bool canClear = true;
 850                 foreach (SqlParameter commandParameter in cmd.Parameters)
 851                 {
 852                     if (commandParameter.Direction != ParameterDirection.Input)
 853                         canClear = false;
 854                 }
 855 
 856                 if (canClear)
 857                 {
 858                     cmd.Parameters.Clear();
 859                 }
 860 
 861                 return dataReader;
 862             }
 863             catch
 864             {
 865                 if (mustCloseConnection)
 866                     connection.Close();
 867                 throw;
 868             }
 869         }
 870 
 871         /// <summary> 
 872         /// 执行指定数据库连接字符串的数据阅读器. 
 873         /// </summary> 
 874         /// <remarks> 
 875         /// 示例:  
 876         ///  SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders"); 
 877         /// </remarks> 
 878         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
 879         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
 880         /// <param name="commandText">存储过程名或T-SQL语句</param> 
 881         /// <returns>返回包含结果集的SqlDataReader</returns> 
 882         public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText)
 883         {
 884             return ExecuteReader(connectionString, commandType, commandText, (SqlParameter[])null);
 885         }
 886 
 887         /// <summary> 
 888         /// 执行指定数据库连接字符串的数据阅读器,指定参数. 
 889         /// </summary> 
 890         /// <remarks> 
 891         /// 示例:  
 892         ///  SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); 
 893         /// </remarks> 
 894         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
 895         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
 896         /// <param name="commandText">存储过程名或T-SQL语句</param> 
 897         /// <param name="commandParameters">SqlParamter参数数组(new SqlParameter("@prodid", 24))</param> 
 898         /// <returns>返回包含结果集的SqlDataReader</returns> 
 899         public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 900         {
 901             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
 902             SqlConnection connection = null;
 903             try
 904             {
 905                 connection = new SqlConnection(connectionString);
 906                 connection.Open();
 907 
 908                 return ExecuteReader(connection, null, commandType, commandText, commandParameters, SqlConnectionOwnership.Internal);
 909             }
 910             catch
 911             {
 912                 if (connection != null) connection.Close();
 913                 throw;
 914             }
 915         }
 916 
 917         /// <summary> 
 918         /// 执行指定数据库连接字符串的数据阅读器,指定参数值. 
 919         /// </summary> 
 920         /// <remarks> 
 921         /// 此方法不提供访问存储过程输出参数和返回值参数. 
 922         /// 示例:  
 923         ///  SqlDataReader dr = ExecuteReader(connString, "GetOrders", 24, 36); 
 924         /// </remarks> 
 925         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
 926         /// <param name="spName">存储过程名</param> 
 927         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
 928         /// <returns>返回包含结果集的SqlDataReader</returns> 
 929         public static SqlDataReader ExecuteReader(string connectionString, string spName, params object[] parameterValues)
 930         {
 931             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
 932             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
 933 
 934             if ((parameterValues != null) && (parameterValues.Length > 0))
 935             {
 936                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
 937 
 938                 AssignParameterValues(commandParameters, parameterValues);
 939 
 940                 return ExecuteReader(connectionString, CommandType.StoredProcedure, spName, commandParameters);
 941             }
 942             else
 943             {
 944                 return ExecuteReader(connectionString, CommandType.StoredProcedure, spName);
 945             }
 946         }
 947 
 948         /// <summary> 
 949         /// 执行指定数据库连接对象的数据阅读器. 
 950         /// </summary> 
 951         /// <remarks> 
 952         /// 示例:  
 953         ///  SqlDataReader dr = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders"); 
 954         /// </remarks> 
 955         /// <param name="connection">一个有效的数据库连接对象</param> 
 956         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
 957         /// <param name="commandText">存储过程名或T-SQL语句</param> 
 958         /// <returns>返回包含结果集的SqlDataReader</returns> 
 959         public static SqlDataReader ExecuteReader(SqlConnection connection, CommandType commandType, string commandText)
 960         {
 961             return ExecuteReader(connection, commandType, commandText, (SqlParameter[])null);
 962         }
 963 
 964         /// <summary> 
 965         /// [调用者方式]执行指定数据库连接对象的数据阅读器,指定参数. 
 966         /// </summary> 
 967         /// <remarks> 
 968         /// 示例:  
 969         ///  SqlDataReader dr = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); 
 970         /// </remarks> 
 971         /// <param name="connection">一个有效的数据库连接对象</param> 
 972         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
 973         /// <param name="commandText">命令类型 (存储过程,命令文本或其它)</param> 
 974         /// <param name="commandParameters">SqlParamter参数数组</param> 
 975         /// <returns>返回包含结果集的SqlDataReader</returns> 
 976         public static SqlDataReader ExecuteReader(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
 977         {
 978             return ExecuteReader(connection, (SqlTransaction)null, commandType, commandText, commandParameters, SqlConnectionOwnership.External);
 979         }
 980 
 981         /// <summary> 
 982         /// [调用者方式]执行指定数据库连接对象的数据阅读器,指定参数值. 
 983         /// </summary> 
 984         /// <remarks> 
 985         /// 此方法不提供访问存储过程输出参数和返回值参数. 
 986         /// 示例:  
 987         ///  SqlDataReader dr = ExecuteReader(conn, "GetOrders", 24, 36); 
 988         /// </remarks> 
 989         /// <param name="connection">一个有效的数据库连接对象</param> 
 990         /// <param name="spName">T存储过程名</param> 
 991         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
 992         /// <returns>返回包含结果集的SqlDataReader</returns> 
 993         public static SqlDataReader ExecuteReader(SqlConnection connection, string spName, params object[] parameterValues)
 994         {
 995             if (connection == null) throw new ArgumentNullException("connection");
 996             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
 997 
 998             if ((parameterValues != null) && (parameterValues.Length > 0))
 999             {
1000                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
1001 
1002                 AssignParameterValues(commandParameters, parameterValues);
1003 
1004                 return ExecuteReader(connection, CommandType.StoredProcedure, spName, commandParameters);
1005             }
1006             else
1007             {
1008                 return ExecuteReader(connection, CommandType.StoredProcedure, spName);
1009             }
1010         }
1011 
1012         /// <summary> 
1013         /// [调用者方式]执行指定数据库事务的数据阅读器,指定参数值. 
1014         /// </summary> 
1015         /// <remarks> 
1016         /// 示例:  
1017         ///  SqlDataReader dr = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders"); 
1018         /// </remarks> 
1019         /// <param name="transaction">一个有效的连接事务</param> 
1020         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1021         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1022         /// <returns>返回包含结果集的SqlDataReader</returns> 
1023         public static SqlDataReader ExecuteReader(SqlTransaction transaction, CommandType commandType, string commandText)
1024         {
1025             return ExecuteReader(transaction, commandType, commandText, (SqlParameter[])null);
1026         }
1027 
1028         /// <summary> 
1029         /// [调用者方式]执行指定数据库事务的数据阅读器,指定参数. 
1030         /// </summary> 
1031         /// <remarks> 
1032         /// 示例:  
1033         ///   SqlDataReader dr = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); 
1034         /// </remarks> 
1035         /// <param name="transaction">一个有效的连接事务</param> 
1036         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1037         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1038         /// <param name="commandParameters">分配给命令的SqlParamter参数数组</param> 
1039         /// <returns>返回包含结果集的SqlDataReader</returns> 
1040         public static SqlDataReader ExecuteReader(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
1041         {
1042             if (transaction == null) throw new ArgumentNullException("transaction");
1043             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
1044 
1045             return ExecuteReader(transaction.Connection, transaction, commandType, commandText, commandParameters, SqlConnectionOwnership.External);
1046         }
1047 
1048         /// <summary> 
1049         /// [调用者方式]执行指定数据库事务的数据阅读器,指定参数值. 
1050         /// </summary> 
1051         /// <remarks> 
1052         /// 此方法不提供访问存储过程输出参数和返回值参数. 
1053         /// 
1054         /// 示例:  
1055         ///  SqlDataReader dr = ExecuteReader(trans, "GetOrders", 24, 36); 
1056         /// </remarks> 
1057         /// <param name="transaction">一个有效的连接事务</param> 
1058         /// <param name="spName">存储过程名称</param> 
1059         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
1060         /// <returns>返回包含结果集的SqlDataReader</returns> 
1061         public static SqlDataReader ExecuteReader(SqlTransaction transaction, string spName, params object[] parameterValues)
1062         {
1063             if (transaction == null) throw new ArgumentNullException("transaction");
1064             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
1065             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
1066 
1067             // 如果有参数值 
1068             if ((parameterValues != null) && (parameterValues.Length > 0))
1069             {
1070                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
1071 
1072                 AssignParameterValues(commandParameters, parameterValues);
1073 
1074                 return ExecuteReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
1075             }
1076             else
1077             {
1078                 // 没有参数值 
1079                 return ExecuteReader(transaction, CommandType.StoredProcedure, spName);
1080             }
1081         }
1082 
1083         #endregion ExecuteReader数据阅读器
1084 
1085         #region ExecuteScalar 返回结果集中的第一行第一列
1086 
1087         /// <summary> 
1088         /// 执行指定数据库连接字符串的命令,返回结果集中的第一行第一列. 
1089         /// </summary> 
1090         /// <remarks> 
1091         /// 示例:  
1092         ///  int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount");
1093         /// </remarks> 
1094         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
1095         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1096         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1097         /// <returns>返回结果集中的第一行第一列</returns> 
1098         public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText)
1099         {
1100             // 执行参数为空的方法 
1101             return ExecuteScalar(connectionString, commandType, commandText, (SqlParameter[])null);
1102         }
1103 
1104         /// <summary> 
1105         /// 执行指定数据库连接字符串的命令,指定参数,返回结果集中的第一行第一列. 
1106         /// </summary> 
1107         /// <remarks> 
1108         /// 示例:  
1109         ///  int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24)); 
1110         /// </remarks> 
1111         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
1112         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1113         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1114         /// <param name="commandParameters">分配给命令的SqlParamter参数数组</param> 
1115         /// <returns>返回结果集中的第一行第一列</returns> 
1116         public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
1117         {
1118             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
1119             // 创建并打开数据库连接对象,操作完成释放对象. 
1120             using (SqlConnection connection = new SqlConnection(connectionString))
1121             {
1122                 connection.Open();
1123 
1124                 // 调用指定数据库连接字符串重载方法. 
1125                 return ExecuteScalar(connection, commandType, commandText, commandParameters);
1126             }
1127         }
1128 
1129         /// <summary> 
1130         /// 执行指定数据库连接字符串的命令,指定参数值,返回结果集中的第一行第一列. 
1131         /// </summary> 
1132         /// <remarks> 
1133         /// 此方法不提供访问存储过程输出参数和返回值参数. 
1134         /// 
1135         /// 示例:  
1136         ///  int orderCount = (int)ExecuteScalar(connString, "GetOrderCount", 24, 36); 
1137         /// </remarks> 
1138         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
1139         /// <param name="spName">存储过程名称</param> 
1140         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
1141         /// <returns>返回结果集中的第一行第一列</returns> 
1142         public static object ExecuteScalar(string connectionString, string spName, params object[] parameterValues)
1143         {
1144             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
1145             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
1146 
1147             // 如果有参数值 
1148             if ((parameterValues != null) && (parameterValues.Length > 0))
1149             {
1150                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
1151                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
1152 
1153                 // 给存储过程参数赋值 
1154                 AssignParameterValues(commandParameters, parameterValues);
1155 
1156                 // 调用重载方法 
1157                 return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName, commandParameters);
1158             }
1159             else
1160             {
1161                 // 没有参数值 
1162                 return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName);
1163             }
1164         }
1165 
1166         /// <summary> 
1167         /// 执行指定数据库连接对象的命令,返回结果集中的第一行第一列. 
1168         /// </summary> 
1169         /// <remarks> 
1170         /// 示例:  
1171         ///  int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount"); 
1172         /// </remarks> 
1173         /// <param name="connection">一个有效的数据库连接对象</param> 
1174         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1175         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1176         /// <returns>返回结果集中的第一行第一列</returns> 
1177         public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText)
1178         {
1179             // 执行参数为空的方法 
1180             return ExecuteScalar(connection, commandType, commandText, (SqlParameter[])null);
1181         }
1182 
1183         /// <summary> 
1184         /// 执行指定数据库连接对象的命令,指定参数,返回结果集中的第一行第一列. 
1185         /// </summary> 
1186         /// <remarks> 
1187         /// 示例:  
1188         ///  int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24)); 
1189         /// </remarks> 
1190         /// <param name="connection">一个有效的数据库连接对象</param> 
1191         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1192         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1193         /// <param name="commandParameters">分配给命令的SqlParamter参数数组</param> 
1194         /// <returns>返回结果集中的第一行第一列</returns> 
1195         public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
1196         {
1197             if (connection == null) throw new ArgumentNullException("connection");
1198 
1199             // 创建SqlCommand命令,并进行预处理 
1200             SqlCommand cmd = new SqlCommand();
1201 
1202             bool mustCloseConnection = false;
1203             PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);
1204 
1205             // 执行SqlCommand命令,并返回结果. 
1206             object retval = cmd.ExecuteScalar();
1207 
1208             // 清除参数,以便再次使用. 
1209             cmd.Parameters.Clear();
1210 
1211             if (mustCloseConnection)
1212                 connection.Close();
1213 
1214             return retval;
1215         }
1216 
1217         /// <summary> 
1218         /// 执行指定数据库连接对象的命令,指定参数值,返回结果集中的第一行第一列. 
1219         /// </summary> 
1220         /// <remarks> 
1221         /// 此方法不提供访问存储过程输出参数和返回值参数. 
1222         /// 
1223         /// 示例:  
1224         ///  int orderCount = (int)ExecuteScalar(conn, "GetOrderCount", 24, 36); 
1225         /// </remarks> 
1226         /// <param name="connection">一个有效的数据库连接对象</param> 
1227         /// <param name="spName">存储过程名称</param> 
1228         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
1229         /// <returns>返回结果集中的第一行第一列</returns> 
1230         public static object ExecuteScalar(SqlConnection connection, string spName, params object[] parameterValues)
1231         {
1232             if (connection == null) throw new ArgumentNullException("connection");
1233             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
1234 
1235             // 如果有参数值 
1236             if ((parameterValues != null) && (parameterValues.Length > 0))
1237             {
1238                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
1239                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
1240 
1241                 // 给存储过程参数赋值 
1242                 AssignParameterValues(commandParameters, parameterValues);
1243 
1244                 // 调用重载方法 
1245                 return ExecuteScalar(connection, CommandType.StoredProcedure, spName, commandParameters);
1246             }
1247             else
1248             {
1249                 // 没有参数值 
1250                 return ExecuteScalar(connection, CommandType.StoredProcedure, spName);
1251             }
1252         }
1253 
1254         /// <summary> 
1255         /// 执行指定数据库事务的命令,返回结果集中的第一行第一列. 
1256         /// </summary> 
1257         /// <remarks> 
1258         /// 示例:  
1259         ///  int orderCount = (int)ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount"); 
1260         /// </remarks> 
1261         /// <param name="transaction">一个有效的连接事务</param> 
1262         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1263         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1264         /// <returns>返回结果集中的第一行第一列</returns> 
1265         public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText)
1266         {
1267             // 执行参数为空的方法 
1268             return ExecuteScalar(transaction, commandType, commandText, (SqlParameter[])null);
1269         }
1270 
1271         /// <summary> 
1272         /// 执行指定数据库事务的命令,指定参数,返回结果集中的第一行第一列. 
1273         /// </summary> 
1274         /// <remarks> 
1275         /// 示例:  
1276         ///  int orderCount = (int)ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24)); 
1277         /// </remarks> 
1278         /// <param name="transaction">一个有效的连接事务</param> 
1279         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1280         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1281         /// <param name="commandParameters">分配给命令的SqlParamter参数数组</param> 
1282         /// <returns>返回结果集中的第一行第一列</returns> 
1283         public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
1284         {
1285             if (transaction == null) throw new ArgumentNullException("transaction");
1286             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
1287 
1288             // 创建SqlCommand命令,并进行预处理 
1289             SqlCommand cmd = new SqlCommand();
1290             bool mustCloseConnection = false;
1291             PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
1292 
1293             // 执行SqlCommand命令,并返回结果. 
1294             object retval = cmd.ExecuteScalar();
1295 
1296             // 清除参数,以便再次使用. 
1297             cmd.Parameters.Clear();
1298             return retval;
1299         }
1300 
1301         /// <summary> 
1302         /// 执行指定数据库事务的命令,指定参数值,返回结果集中的第一行第一列. 
1303         /// </summary> 
1304         /// <remarks> 
1305         /// 此方法不提供访问存储过程输出参数和返回值参数. 
1306         /// 
1307         /// 示例:  
1308         ///  int orderCount = (int)ExecuteScalar(trans, "GetOrderCount", 24, 36); 
1309         /// </remarks> 
1310         /// <param name="transaction">一个有效的连接事务</param> 
1311         /// <param name="spName">存储过程名称</param> 
1312         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
1313         /// <returns>返回结果集中的第一行第一列</returns> 
1314         public static object ExecuteScalar(SqlTransaction transaction, string spName, params object[] parameterValues)
1315         {
1316             if (transaction == null) throw new ArgumentNullException("transaction");
1317             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
1318             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
1319 
1320             // 如果有参数值 
1321             if ((parameterValues != null) && (parameterValues.Length > 0))
1322             {
1323                 // PPull the parameters for this stored procedure from the parameter cache () 
1324                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
1325 
1326                 // 给存储过程参数赋值 
1327                 AssignParameterValues(commandParameters, parameterValues);
1328 
1329                 // 调用重载方法 
1330                 return ExecuteScalar(transaction, CommandType.StoredProcedure, spName, commandParameters);
1331             }
1332             else
1333             {
1334                 // 没有参数值 
1335                 return ExecuteScalar(transaction, CommandType.StoredProcedure, spName);
1336             }
1337         }
1338 
1339         #endregion ExecuteScalar
1340 
1341         #region ExecuteXmlReader XML阅读器
1342         /// <summary> 
1343         /// 执行指定数据库连接对象的SqlCommand命令,并产生一个XmlReader对象做为结果集返回. 
1344         /// </summary> 
1345         /// <remarks> 
1346         /// 示例:  
1347         ///  XmlReader r = ExecuteXmlReader(conn, CommandType.StoredProcedure, "GetOrders"); 
1348         /// </remarks> 
1349         /// <param name="connection">一个有效的数据库连接对象</param> 
1350         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1351         /// <param name="commandText">存储过程名称或T-SQL语句 using "FOR XML AUTO"</param> 
1352         /// <returns>返回XmlReader结果集对象.</returns> 
1353         public static XmlReader ExecuteXmlReader(SqlConnection connection, CommandType commandType, string commandText)
1354         {
1355             // 执行参数为空的方法 
1356             return ExecuteXmlReader(connection, commandType, commandText, (SqlParameter[])null);
1357         }
1358 
1359         /// <summary> 
1360         /// 执行指定数据库连接对象的SqlCommand命令,并产生一个XmlReader对象做为结果集返回,指定参数. 
1361         /// </summary> 
1362         /// <remarks> 
1363         /// 示例:  
1364         ///  XmlReader r = ExecuteXmlReader(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); 
1365         /// </remarks> 
1366         /// <param name="connection">一个有效的数据库连接对象</param> 
1367         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1368         /// <param name="commandText">存储过程名称或T-SQL语句 using "FOR XML AUTO"</param> 
1369         /// <param name="commandParameters">分配给命令的SqlParamter参数数组</param> 
1370         /// <returns>返回XmlReader结果集对象.</returns> 
1371         public static XmlReader ExecuteXmlReader(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
1372         {
1373             if (connection == null) throw new ArgumentNullException("connection");
1374 
1375             bool mustCloseConnection = false;
1376             // 创建SqlCommand命令,并进行预处理 
1377             SqlCommand cmd = new SqlCommand();
1378             try
1379             {
1380                 PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);
1381 
1382                 // 执行命令 
1383                 XmlReader retval = cmd.ExecuteXmlReader();
1384 
1385                 // 清除参数,以便再次使用. 
1386                 cmd.Parameters.Clear();
1387 
1388                 return retval;
1389             }
1390             catch
1391             {
1392                 if (mustCloseConnection)
1393                     connection.Close();
1394                 throw;
1395             }
1396         }
1397 
1398         /// <summary> 
1399         /// 执行指定数据库连接对象的SqlCommand命令,并产生一个XmlReader对象做为结果集返回,指定参数值. 
1400         /// </summary> 
1401         /// <remarks> 
1402         /// 此方法不提供访问存储过程输出参数和返回值参数. 
1403         /// 
1404         /// 示例:  
1405         ///  XmlReader r = ExecuteXmlReader(conn, "GetOrders", 24, 36); 
1406         /// </remarks> 
1407         /// <param name="connection">一个有效的数据库连接对象</param> 
1408         /// <param name="spName">存储过程名称 using "FOR XML AUTO"</param> 
1409         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
1410         /// <returns>返回XmlReader结果集对象.</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             // 如果有参数值 
1417             if ((parameterValues != null) && (parameterValues.Length > 0))
1418             {
1419                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
1420                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
1421 
1422                 // 给存储过程参数赋值 
1423                 AssignParameterValues(commandParameters, parameterValues);
1424 
1425                 // 调用重载方法 
1426                 return ExecuteXmlReader(connection, CommandType.StoredProcedure, spName, commandParameters);
1427             }
1428             else
1429             {
1430                 // 没有参数值 
1431                 return ExecuteXmlReader(connection, CommandType.StoredProcedure, spName);
1432             }
1433         }
1434 
1435         /// <summary> 
1436         /// 执行指定数据库事务的SqlCommand命令,并产生一个XmlReader对象做为结果集返回. 
1437         /// </summary> 
1438         /// <remarks> 
1439         /// 示例:  
1440         ///  XmlReader r = ExecuteXmlReader(trans, CommandType.StoredProcedure, "GetOrders"); 
1441         /// </remarks> 
1442         /// <param name="transaction">一个有效的连接事务</param> 
1443         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1444         /// <param name="commandText">存储过程名称或T-SQL语句 using "FOR XML AUTO"</param> 
1445         /// <returns>返回XmlReader结果集对象.</returns> 
1446         public static XmlReader ExecuteXmlReader(SqlTransaction transaction, CommandType commandType, string commandText)
1447         {
1448             // 执行参数为空的方法 
1449             return ExecuteXmlReader(transaction, commandType, commandText, (SqlParameter[])null);
1450         }
1451 
1452         /// <summary> 
1453         /// 执行指定数据库事务的SqlCommand命令,并产生一个XmlReader对象做为结果集返回,指定参数. 
1454         /// </summary> 
1455         /// <remarks> 
1456         /// 示例:  
1457         ///  XmlReader r = ExecuteXmlReader(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); 
1458         /// </remarks> 
1459         /// <param name="transaction">一个有效的连接事务</param> 
1460         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1461         /// <param name="commandText">存储过程名称或T-SQL语句 using "FOR XML AUTO"</param> 
1462         /// <param name="commandParameters">分配给命令的SqlParamter参数数组</param> 
1463         /// <returns>返回XmlReader结果集对象.</returns> 
1464         public static XmlReader ExecuteXmlReader(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
1465         {
1466             if (transaction == null) throw new ArgumentNullException("transaction");
1467             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
1468 
1469             // 创建SqlCommand命令,并进行预处理 
1470             SqlCommand cmd = new SqlCommand();
1471             bool mustCloseConnection = false;
1472             PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
1473 
1474             // 执行命令 
1475             XmlReader retval = cmd.ExecuteXmlReader();
1476 
1477             // 清除参数,以便再次使用. 
1478             cmd.Parameters.Clear();
1479             return retval;
1480         }
1481 
1482         /// <summary> 
1483         /// 执行指定数据库事务的SqlCommand命令,并产生一个XmlReader对象做为结果集返回,指定参数值. 
1484         /// </summary> 
1485         /// <remarks> 
1486         /// 此方法不提供访问存储过程输出参数和返回值参数. 
1487         /// 
1488         /// 示例:  
1489         ///  XmlReader r = ExecuteXmlReader(trans, "GetOrders", 24, 36); 
1490         /// </remarks> 
1491         /// <param name="transaction">一个有效的连接事务</param> 
1492         /// <param name="spName">存储过程名称</param> 
1493         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
1494         /// <returns>返回一个包含结果集的DataSet.</returns> 
1495         public static XmlReader ExecuteXmlReader(SqlTransaction transaction, string spName, params object[] parameterValues)
1496         {
1497             if (transaction == null) throw new ArgumentNullException("transaction");
1498             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
1499             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
1500 
1501             // 如果有参数值 
1502             if ((parameterValues != null) && (parameterValues.Length > 0))
1503             {
1504                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
1505                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
1506 
1507                 // 给存储过程参数赋值 
1508                 AssignParameterValues(commandParameters, parameterValues);
1509 
1510                 // 调用重载方法 
1511                 return ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
1512             }
1513             else
1514             {
1515                 // 没有参数值 
1516                 return ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName);
1517             }
1518         }
1519 
1520         #endregion ExecuteXmlReader 阅读器结束
1521 
1522         #region FillDataset 填充数据集
1523         /// <summary> 
1524         /// 执行指定数据库连接字符串的命令,映射数据表并填充数据集. 
1525         /// </summary> 
1526         /// <remarks> 
1527         /// 示例:  
1528         ///  FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}); 
1529         /// </remarks> 
1530         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
1531         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1532         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1533         /// <param name="dataSet">要填充结果集的DataSet实例</param> 
1534         /// <param name="tableNames">表映射的数据表数组 
1535         /// 用户定义的表名 (可有是实际的表名.)</param> 
1536         public static void FillDataset(string connectionString, CommandType commandType, string commandText, DataSet dataSet, string[] tableNames)
1537         {
1538             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
1539             if (dataSet == null) throw new ArgumentNullException("dataSet");
1540 
1541             // 创建并打开数据库连接对象,操作完成释放对象. 
1542             using (SqlConnection connection = new SqlConnection(connectionString))
1543             {
1544                 connection.Open();
1545 
1546                 // 调用指定数据库连接字符串重载方法. 
1547                 FillDataset(connection, commandType, commandText, dataSet, tableNames);
1548             }
1549         }
1550 
1551         /// <summary> 
1552         /// 执行指定数据库连接字符串的命令,映射数据表并填充数据集.指定命令参数. 
1553         /// </summary> 
1554         /// <remarks> 
1555         /// 示例:  
1556         ///  FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24)); 
1557         /// </remarks> 
1558         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
1559         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1560         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1561         /// <param name="commandParameters">分配给命令的SqlParamter参数数组</param> 
1562         /// <param name="dataSet">要填充结果集的DataSet实例</param> 
1563         /// <param name="tableNames">表映射的数据表数组 
1564         /// 用户定义的表名 (可有是实际的表名.) 
1565         /// </param> 
1566         public static void FillDataset(string connectionString, CommandType commandType,
1567             string commandText, DataSet dataSet, string[] tableNames,
1568             params SqlParameter[] commandParameters)
1569         {
1570             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
1571             if (dataSet == null) throw new ArgumentNullException("dataSet");
1572             // 创建并打开数据库连接对象,操作完成释放对象. 
1573             using (SqlConnection connection = new SqlConnection(connectionString))
1574             {
1575                 connection.Open();
1576 
1577                 // 调用指定数据库连接字符串重载方法. 
1578                 FillDataset(connection, commandType, commandText, dataSet, tableNames, commandParameters);
1579             }
1580         }
1581 
1582         /// <summary> 
1583         /// 执行指定数据库连接字符串的命令,映射数据表并填充数据集,指定存储过程参数值. 
1584         /// </summary> 
1585         /// <remarks> 
1586         /// 此方法不提供访问存储过程输出参数和返回值参数. 
1587         /// 
1588         /// 示例:  
1589         ///  FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, 24); 
1590         /// </remarks> 
1591         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
1592         /// <param name="spName">存储过程名称</param> 
1593         /// <param name="dataSet">要填充结果集的DataSet实例</param> 
1594         /// <param name="tableNames">表映射的数据表数组 
1595         /// 用户定义的表名 (可有是实际的表名.) 
1596         /// </param>    
1597         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
1598         public static void FillDataset(string connectionString, string spName,
1599             DataSet dataSet, string[] tableNames,
1600             params object[] parameterValues)
1601         {
1602             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
1603             if (dataSet == null) throw new ArgumentNullException("dataSet");
1604             // 创建并打开数据库连接对象,操作完成释放对象. 
1605             using (SqlConnection connection = new SqlConnection(connectionString))
1606             {
1607                 connection.Open();
1608 
1609                 // 调用指定数据库连接字符串重载方法. 
1610                 FillDataset(connection, spName, dataSet, tableNames, parameterValues);
1611             }
1612         }
1613 
1614         /// <summary> 
1615         /// 执行指定数据库连接对象的命令,映射数据表并填充数据集. 
1616         /// </summary> 
1617         /// <remarks> 
1618         /// 示例:  
1619         ///  FillDataset(conn, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}); 
1620         /// </remarks> 
1621         /// <param name="connection">一个有效的数据库连接对象</param> 
1622         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1623         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1624         /// <param name="dataSet">要填充结果集的DataSet实例</param> 
1625         /// <param name="tableNames">表映射的数据表数组 
1626         /// 用户定义的表名 (可有是实际的表名.) 
1627         /// </param>    
1628         public static void FillDataset(SqlConnection connection, CommandType commandType,
1629             string commandText, DataSet dataSet, string[] tableNames)
1630         {
1631             FillDataset(connection, commandType, commandText, dataSet, tableNames, null);
1632         }
1633 
1634         /// <summary> 
1635         /// 执行指定数据库连接对象的命令,映射数据表并填充数据集,指定参数. 
1636         /// </summary> 
1637         /// <remarks> 
1638         /// 示例:  
1639         ///  FillDataset(conn, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24)); 
1640         /// </remarks> 
1641         /// <param name="connection">一个有效的数据库连接对象</param> 
1642         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1643         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1644         /// <param name="dataSet">要填充结果集的DataSet实例</param> 
1645         /// <param name="tableNames">表映射的数据表数组 
1646         /// 用户定义的表名 (可有是实际的表名.) 
1647         /// </param> 
1648         /// <param name="commandParameters">分配给命令的SqlParamter参数数组</param> 
1649         public static void FillDataset(SqlConnection connection, CommandType commandType,
1650             string commandText, DataSet dataSet, string[] tableNames,
1651             params SqlParameter[] commandParameters)
1652         {
1653             FillDataset(connection, null, commandType, commandText, dataSet, tableNames, commandParameters);
1654         }
1655 
1656         /// <summary> 
1657         /// 执行指定数据库连接对象的命令,映射数据表并填充数据集,指定存储过程参数值. 
1658         /// </summary> 
1659         /// <remarks> 
1660         /// 此方法不提供访问存储过程输出参数和返回值参数. 
1661         /// 
1662         /// 示例:  
1663         ///  FillDataset(conn, "GetOrders", ds, new string[] {"orders"}, 24, 36); 
1664         /// </remarks> 
1665         /// <param name="connection">一个有效的数据库连接对象</param> 
1666         /// <param name="spName">存储过程名称</param> 
1667         /// <param name="dataSet">要填充结果集的DataSet实例</param> 
1668         /// <param name="tableNames">表映射的数据表数组 
1669         /// 用户定义的表名 (可有是实际的表名.) 
1670         /// </param> 
1671         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
1672         public static void FillDataset(SqlConnection connection, string spName,
1673             DataSet dataSet, string[] tableNames,
1674             params object[] parameterValues)
1675         {
1676             if (connection == null) throw new ArgumentNullException("connection");
1677             if (dataSet == null) throw new ArgumentNullException("dataSet");
1678             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
1679 
1680             // 如果有参数值 
1681             if ((parameterValues != null) && (parameterValues.Length > 0))
1682             {
1683                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
1684                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
1685 
1686                 // 给存储过程参数赋值 
1687                 AssignParameterValues(commandParameters, parameterValues);
1688 
1689                 // 调用重载方法 
1690                 FillDataset(connection, CommandType.StoredProcedure, spName, dataSet, tableNames, commandParameters);
1691             }
1692             else
1693             {
1694                 // 没有参数值 
1695                 FillDataset(connection, CommandType.StoredProcedure, spName, dataSet, tableNames);
1696             }
1697         }
1698 
1699         /// <summary> 
1700         /// 执行指定数据库事务的命令,映射数据表并填充数据集. 
1701         /// </summary> 
1702         /// <remarks> 
1703         /// 示例:  
1704         ///  FillDataset(trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}); 
1705         /// </remarks> 
1706         /// <param name="transaction">一个有效的连接事务</param> 
1707         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1708         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1709         /// <param name="dataSet">要填充结果集的DataSet实例</param> 
1710         /// <param name="tableNames">表映射的数据表数组 
1711         /// 用户定义的表名 (可有是实际的表名.) 
1712         /// </param> 
1713         public static void FillDataset(SqlTransaction transaction, CommandType commandType,
1714             string commandText,
1715             DataSet dataSet, string[] tableNames)
1716         {
1717             FillDataset(transaction, commandType, commandText, dataSet, tableNames, null);
1718         }
1719 
1720         /// <summary> 
1721         /// 执行指定数据库事务的命令,映射数据表并填充数据集,指定参数. 
1722         /// </summary> 
1723         /// <remarks> 
1724         /// 示例:  
1725         ///  FillDataset(trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24)); 
1726         /// </remarks> 
1727         /// <param name="transaction">一个有效的连接事务</param> 
1728         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1729         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1730         /// <param name="dataSet">要填充结果集的DataSet实例</param> 
1731         /// <param name="tableNames">表映射的数据表数组 
1732         /// 用户定义的表名 (可有是实际的表名.) 
1733         /// </param> 
1734         /// <param name="commandParameters">分配给命令的SqlParamter参数数组</param> 
1735         public static void FillDataset(SqlTransaction transaction, CommandType commandType,
1736             string commandText, DataSet dataSet, string[] tableNames,
1737             params SqlParameter[] commandParameters)
1738         {
1739             FillDataset(transaction.Connection, transaction, commandType, commandText, dataSet, tableNames, commandParameters);
1740         }
1741 
1742         /// <summary> 
1743         /// 执行指定数据库事务的命令,映射数据表并填充数据集,指定存储过程参数值. 
1744         /// </summary> 
1745         /// <remarks> 
1746         /// 此方法不提供访问存储过程输出参数和返回值参数. 
1747         /// 
1748         /// 示例:  
1749         ///  FillDataset(trans, "GetOrders", ds, new string[]{"orders"}, 24, 36); 
1750         /// </remarks> 
1751         /// <param name="transaction">一个有效的连接事务</param> 
1752         /// <param name="spName">存储过程名称</param> 
1753         /// <param name="dataSet">要填充结果集的DataSet实例</param> 
1754         /// <param name="tableNames">表映射的数据表数组 
1755         /// 用户定义的表名 (可有是实际的表名.) 
1756         /// </param> 
1757         /// <param name="parameterValues">分配给存储过程输入参数的对象数组</param> 
1758         public static void FillDataset(SqlTransaction transaction, string spName,
1759             DataSet dataSet, string[] tableNames,
1760             params object[] parameterValues)
1761         {
1762             if (transaction == null) throw new ArgumentNullException("transaction");
1763             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
1764             if (dataSet == null) throw new ArgumentNullException("dataSet");
1765             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
1766 
1767             // 如果有参数值 
1768             if ((parameterValues != null) && (parameterValues.Length > 0))
1769             {
1770                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
1771                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
1772 
1773                 // 给存储过程参数赋值 
1774                 AssignParameterValues(commandParameters, parameterValues);
1775 
1776                 // 调用重载方法 
1777                 FillDataset(transaction, CommandType.StoredProcedure, spName, dataSet, tableNames, commandParameters);
1778             }
1779             else
1780             {
1781                 // 没有参数值 
1782                 FillDataset(transaction, CommandType.StoredProcedure, spName, dataSet, tableNames);
1783             }
1784         }
1785 
1786         /// <summary> 
1787         /// [私有方法][内部调用]执行指定数据库连接对象/事务的命令,映射数据表并填充数据集,DataSet/TableNames/SqlParameters. 
1788         /// </summary> 
1789         /// <remarks> 
1790         /// 示例:  
1791         ///  FillDataset(conn, trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24)); 
1792         /// </remarks> 
1793         /// <param name="connection">一个有效的数据库连接对象</param> 
1794         /// <param name="transaction">一个有效的连接事务</param> 
1795         /// <param name="commandType">命令类型 (存储过程,命令文本或其它)</param> 
1796         /// <param name="commandText">存储过程名称或T-SQL语句</param> 
1797         /// <param name="dataSet">要填充结果集的DataSet实例</param> 
1798         /// <param name="tableNames">表映射的数据表数组 
1799         /// 用户定义的表名 (可有是实际的表名.) 
1800         /// </param> 
1801         /// <param name="commandParameters">分配给命令的SqlParamter参数数组</param> 
1802         private static void FillDataset(SqlConnection connection, SqlTransaction transaction, CommandType commandType,
1803             string commandText, DataSet dataSet, string[] tableNames,
1804             params SqlParameter[] commandParameters)
1805         {
1806             if (connection == null) throw new ArgumentNullException("connection");
1807             if (dataSet == null) throw new ArgumentNullException("dataSet");
1808 
1809             // 创建SqlCommand命令,并进行预处理 
1810             SqlCommand command = new SqlCommand();
1811             bool mustCloseConnection = false;
1812             PrepareCommand(command, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
1813 
1814             // 执行命令 
1815             using (SqlDataAdapter dataAdapter = new SqlDataAdapter(command))
1816             {
1817 
1818                 // 追加表映射 
1819                 if (tableNames != null && tableNames.Length > 0)
1820                 {
1821                     string tableName = "Table";
1822                     for (int index = 0; index < tableNames.Length; index++)
1823                     {
1824                         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");
1825                         dataAdapter.TableMappings.Add(tableName, tableNames[index]);
1826                         tableName += (index + 1).ToString();
1827                     }
1828                 }
1829 
1830                 // 填充数据集使用默认表名称 
1831                 dataAdapter.Fill(dataSet);
1832 
1833                 // 清除参数,以便再次使用. 
1834                 command.Parameters.Clear();
1835             }
1836 
1837             if (mustCloseConnection)
1838                 connection.Close();
1839         }
1840         #endregion
1841 
1842         #region UpdateDataset 更新数据集
1843         /// <summary> 
1844         /// 执行数据集更新到数据库,指定inserted, updated, or deleted命令. 
1845         /// </summary> 
1846         /// <remarks> 
1847         /// 示例:  
1848         ///  UpdateDataset(conn, insertCommand, deleteCommand, updateCommand, dataSet, "Order"); 
1849         /// </remarks> 
1850         /// <param name="insertCommand">[追加记录]一个有效的T-SQL语句或存储过程</param> 
1851         /// <param name="deleteCommand">[删除记录]一个有效的T-SQL语句或存储过程</param> 
1852         /// <param name="updateCommand">[更新记录]一个有效的T-SQL语句或存储过程</param> 
1853         /// <param name="dataSet">要更新到数据库的DataSet</param> 
1854         /// <param name="tableName">要更新到数据库的DataTable</param> 
1855         public static void UpdateDataset(SqlCommand insertCommand, SqlCommand deleteCommand, SqlCommand updateCommand, DataSet dataSet, string tableName)
1856         {
1857             if (insertCommand == null) throw new ArgumentNullException("insertCommand");
1858             if (deleteCommand == null) throw new ArgumentNullException("deleteCommand");
1859             if (updateCommand == null) throw new ArgumentNullException("updateCommand");
1860             if (tableName == null || tableName.Length == 0) throw new ArgumentNullException("tableName");
1861 
1862             // 创建SqlDataAdapter,当操作完成后释放. 
1863             using (SqlDataAdapter dataAdapter = new SqlDataAdapter())
1864             {
1865                 // 设置数据适配器命令 
1866                 dataAdapter.UpdateCommand = updateCommand;
1867                 dataAdapter.InsertCommand = insertCommand;
1868                 dataAdapter.DeleteCommand = deleteCommand;
1869 
1870                 // 更新数据集改变到数据库 
1871                 dataAdapter.Update(dataSet, tableName);
1872 
1873                 // 提交所有改变到数据集. 
1874                 dataSet.AcceptChanges();
1875             }
1876         }
1877         #endregion
1878 
1879         #region CreateCommand 创建一条SqlCommand命令
1880         /// <summary> 
1881         /// 创建SqlCommand命令,指定数据库连接对象,存储过程名和参数. 
1882         /// </summary> 
1883         /// <remarks> 
1884         /// 示例:  
1885         ///  SqlCommand command = CreateCommand(conn, "AddCustomer", "CustomerID", "CustomerName"); 
1886         /// </remarks> 
1887         /// <param name="connection">一个有效的数据库连接对象</param> 
1888         /// <param name="spName">存储过程名称</param> 
1889         /// <param name="sourceColumns">源表的列名称数组</param> 
1890         /// <returns>返回SqlCommand命令</returns> 
1891         public static SqlCommand CreateCommand(SqlConnection connection, string spName, params string[] sourceColumns)
1892         {
1893             if (connection == null) throw new ArgumentNullException("connection");
1894             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
1895 
1896             // 创建命令 
1897             SqlCommand cmd = new SqlCommand(spName, connection);
1898             cmd.CommandType = CommandType.StoredProcedure;
1899 
1900             // 如果有参数值 
1901             if ((sourceColumns != null) && (sourceColumns.Length > 0))
1902             {
1903                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
1904                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
1905 
1906                 // 将源表的列到映射到DataSet命令中. 
1907                 for (int index = 0; index < sourceColumns.Length; index++)
1908                     commandParameters[index].SourceColumn = sourceColumns[index];
1909 
1910                 // Attach the discovered parameters to the SqlCommand object 
1911                 AttachParameters(cmd, commandParameters);
1912             }
1913 
1914             return cmd;
1915         }
1916         #endregion
1917 
1918         #region ExecuteNonQueryTypedParams 类型化参数(DataRow)
1919         /// <summary> 
1920         /// 执行指定连接数据库连接字符串的存储过程,使用DataRow做为参数值,返回受影响的行数. 
1921         /// </summary> 
1922         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
1923         /// <param name="spName">存储过程名称</param> 
1924         /// <param name="dataRow">使用DataRow作为参数值</param> 
1925         /// <returns>返回影响的行数</returns> 
1926         public static int ExecuteNonQueryTypedParams(String connectionString, String spName, DataRow dataRow)
1927         {
1928             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
1929             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
1930 
1931             // 如果row有值,存储过程必须初始化. 
1932             if (dataRow != null && dataRow.ItemArray.Length > 0)
1933             {
1934                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
1935                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
1936 
1937                 // 分配参数值 
1938                 AssignParameterValues(commandParameters, dataRow);
1939 
1940                 return SqlHelper.ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters);
1941             }
1942             else
1943             {
1944                 return SqlHelper.ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName);
1945             }
1946         }
1947 
1948         /// <summary> 
1949         /// 执行指定连接数据库连接对象的存储过程,使用DataRow做为参数值,返回受影响的行数. 
1950         /// </summary> 
1951         /// <param name="connection">一个有效的数据库连接对象</param> 
1952         /// <param name="spName">存储过程名称</param> 
1953         /// <param name="dataRow">使用DataRow作为参数值</param> 
1954         /// <returns>返回影响的行数</returns> 
1955         public static int ExecuteNonQueryTypedParams(SqlConnection connection, String spName, DataRow dataRow)
1956         {
1957             if (connection == null) throw new ArgumentNullException("connection");
1958             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
1959 
1960             // 如果row有值,存储过程必须初始化. 
1961             if (dataRow != null && dataRow.ItemArray.Length > 0)
1962             {
1963                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
1964                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
1965 
1966                 // 分配参数值 
1967                 AssignParameterValues(commandParameters, dataRow);
1968 
1969                 return SqlHelper.ExecuteNonQuery(connection, CommandType.StoredProcedure, spName, commandParameters);
1970             }
1971             else
1972             {
1973                 return SqlHelper.ExecuteNonQuery(connection, CommandType.StoredProcedure, spName);
1974             }
1975         }
1976 
1977         /// <summary> 
1978         /// 执行指定连接数据库事物的存储过程,使用DataRow做为参数值,返回受影响的行数. 
1979         /// </summary> 
1980         /// <param name="transaction">一个有效的连接事务 object</param> 
1981         /// <param name="spName">存储过程名称</param> 
1982         /// <param name="dataRow">使用DataRow作为参数值</param> 
1983         /// <returns>返回影响的行数</returns> 
1984         public static int ExecuteNonQueryTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
1985         {
1986             if (transaction == null) throw new ArgumentNullException("transaction");
1987             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
1988             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
1989 
1990             // Sf the row has values, the store procedure parameters must be initialized 
1991             if (dataRow != null && dataRow.ItemArray.Length > 0)
1992             {
1993                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
1994                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
1995 
1996                 // 分配参数值 
1997                 AssignParameterValues(commandParameters, dataRow);
1998 
1999                 return SqlHelper.ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName, commandParameters);
2000             }
2001             else
2002             {
2003                 return SqlHelper.ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName);
2004             }
2005         }
2006         #endregion
2007 
2008         #region ExecuteDatasetTypedParams 类型化参数(DataRow)
2009         /// <summary> 
2010         /// 执行指定连接数据库连接字符串的存储过程,使用DataRow做为参数值,返回DataSet. 
2011         /// </summary> 
2012         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
2013         /// <param name="spName">存储过程名称</param> 
2014         /// <param name="dataRow">使用DataRow作为参数值</param> 
2015         /// <returns>返回一个包含结果集的DataSet.</returns> 
2016         public static DataSet ExecuteDatasetTypedParams(string connectionString, String spName, DataRow dataRow)
2017         {
2018             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
2019             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
2020 
2021             //如果row有值,存储过程必须初始化. 
2022             if (dataRow != null && dataRow.ItemArray.Length > 0)
2023             {
2024                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
2025                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
2026 
2027                 // 分配参数值 
2028                 AssignParameterValues(commandParameters, dataRow);
2029 
2030                 return SqlHelper.ExecuteDataset(connectionString, CommandType.StoredProcedure, spName, commandParameters);
2031             }
2032             else
2033             {
2034                 return SqlHelper.ExecuteDataset(connectionString, CommandType.StoredProcedure, spName);
2035             }
2036         }
2037 
2038         /// <summary> 
2039         /// 执行指定连接数据库连接对象的存储过程,使用DataRow做为参数值,返回DataSet. 
2040         /// </summary> 
2041         /// <param name="connection">一个有效的数据库连接对象</param> 
2042         /// <param name="spName">存储过程名称</param> 
2043         /// <param name="dataRow">使用DataRow作为参数值</param> 
2044         /// <returns>返回一个包含结果集的DataSet.</returns> 
2045         /// 
2046         public static DataSet ExecuteDatasetTypedParams(SqlConnection connection, String spName, DataRow dataRow)
2047         {
2048             if (connection == null) throw new ArgumentNullException("connection");
2049             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
2050 
2051             // 如果row有值,存储过程必须初始化. 
2052             if (dataRow != null && dataRow.ItemArray.Length > 0)
2053             {
2054                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
2055                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
2056 
2057                 // 分配参数值 
2058                 AssignParameterValues(commandParameters, dataRow);
2059 
2060                 return SqlHelper.ExecuteDataset(connection, CommandType.StoredProcedure, spName, commandParameters);
2061             }
2062             else
2063             {
2064                 return SqlHelper.ExecuteDataset(connection, CommandType.StoredProcedure, spName);
2065             }
2066         }
2067 
2068         /// <summary> 
2069         /// 执行指定连接数据库事务的存储过程,使用DataRow做为参数值,返回DataSet. 
2070         /// </summary> 
2071         /// <param name="transaction">一个有效的连接事务 object</param> 
2072         /// <param name="spName">存储过程名称</param> 
2073         /// <param name="dataRow">使用DataRow作为参数值</param> 
2074         /// <returns>返回一个包含结果集的DataSet.</returns> 
2075         public static DataSet ExecuteDatasetTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
2076         {
2077             if (transaction == null) throw new ArgumentNullException("transaction");
2078             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
2079             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
2080 
2081             // 如果row有值,存储过程必须初始化. 
2082             if (dataRow != null && dataRow.ItemArray.Length > 0)
2083             {
2084                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
2085                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
2086 
2087                 // 分配参数值 
2088                 AssignParameterValues(commandParameters, dataRow);
2089 
2090                 return SqlHelper.ExecuteDataset(transaction, CommandType.StoredProcedure, spName, commandParameters);
2091             }
2092             else
2093             {
2094                 return SqlHelper.ExecuteDataset(transaction, CommandType.StoredProcedure, spName);
2095             }
2096         }
2097 
2098         #endregion
2099 
2100         #region ExecuteReaderTypedParams 类型化参数(DataRow)
2101         /// <summary> 
2102         /// 执行指定连接数据库连接字符串的存储过程,使用DataRow做为参数值,返回DataReader. 
2103         /// </summary> 
2104         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
2105         /// <param name="spName">存储过程名称</param> 
2106         /// <param name="dataRow">使用DataRow作为参数值</param> 
2107         /// <returns>返回包含结果集的SqlDataReader</returns> 
2108         public static SqlDataReader ExecuteReaderTypedParams(String connectionString, String spName, DataRow dataRow)
2109         {
2110             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
2111             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
2112 
2113             // 如果row有值,存储过程必须初始化. 
2114             if (dataRow != null && dataRow.ItemArray.Length > 0)
2115             {
2116                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
2117                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
2118 
2119                 // 分配参数值 
2120                 AssignParameterValues(commandParameters, dataRow);
2121 
2122                 return SqlHelper.ExecuteReader(connectionString, CommandType.StoredProcedure, spName, commandParameters);
2123             }
2124             else
2125             {
2126                 return SqlHelper.ExecuteReader(connectionString, CommandType.StoredProcedure, spName);
2127             }
2128         }
2129 
2130 
2131         /// <summary> 
2132         /// 执行指定连接数据库连接对象的存储过程,使用DataRow做为参数值,返回DataReader. 
2133         /// </summary> 
2134         /// <param name="connection">一个有效的数据库连接对象</param> 
2135         /// <param name="spName">存储过程名称</param> 
2136         /// <param name="dataRow">使用DataRow作为参数值</param> 
2137         /// <returns>返回包含结果集的SqlDataReader</returns> 
2138         public static SqlDataReader ExecuteReaderTypedParams(SqlConnection connection, String spName, DataRow dataRow)
2139         {
2140             if (connection == null) throw new ArgumentNullException("connection");
2141             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
2142 
2143             // 如果row有值,存储过程必须初始化. 
2144             if (dataRow != null && dataRow.ItemArray.Length > 0)
2145             {
2146                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
2147                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
2148 
2149                 // 分配参数值 
2150                 AssignParameterValues(commandParameters, dataRow);
2151 
2152                 return SqlHelper.ExecuteReader(connection, CommandType.StoredProcedure, spName, commandParameters);
2153             }
2154             else
2155             {
2156                 return SqlHelper.ExecuteReader(connection, CommandType.StoredProcedure, spName);
2157             }
2158         }
2159 
2160         /// <summary> 
2161         /// 执行指定连接数据库事物的存储过程,使用DataRow做为参数值,返回DataReader. 
2162         /// </summary> 
2163         /// <param name="transaction">一个有效的连接事务 object</param> 
2164         /// <param name="spName">存储过程名称</param> 
2165         /// <param name="dataRow">使用DataRow作为参数值</param> 
2166         /// <returns>返回包含结果集的SqlDataReader</returns> 
2167         public static SqlDataReader ExecuteReaderTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
2168         {
2169             if (transaction == null) throw new ArgumentNullException("transaction");
2170             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
2171             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
2172 
2173             // 如果row有值,存储过程必须初始化. 
2174             if (dataRow != null && dataRow.ItemArray.Length > 0)
2175             {
2176                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
2177                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
2178 
2179                 // 分配参数值 
2180                 AssignParameterValues(commandParameters, dataRow);
2181 
2182                 return SqlHelper.ExecuteReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
2183             }
2184             else
2185             {
2186                 return SqlHelper.ExecuteReader(transaction, CommandType.StoredProcedure, spName);
2187             }
2188         }
2189         #endregion
2190 
2191         #region ExecuteScalarTypedParams 类型化参数(DataRow)
2192         /// <summary> 
2193         /// 执行指定连接数据库连接字符串的存储过程,使用DataRow做为参数值,返回结果集中的第一行第一列. 
2194         /// </summary> 
2195         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
2196         /// <param name="spName">存储过程名称</param> 
2197         /// <param name="dataRow">使用DataRow作为参数值</param> 
2198         /// <returns>返回结果集中的第一行第一列</returns> 
2199         public static object ExecuteScalarTypedParams(String connectionString, String spName, DataRow dataRow)
2200         {
2201             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
2202             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
2203 
2204             // 如果row有值,存储过程必须初始化. 
2205             if (dataRow != null && dataRow.ItemArray.Length > 0)
2206             {
2207                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
2208                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
2209 
2210                 // 分配参数值 
2211                 AssignParameterValues(commandParameters, dataRow);
2212 
2213                 return SqlHelper.ExecuteScalar(connectionString, CommandType.StoredProcedure, spName, commandParameters);
2214             }
2215             else
2216             {
2217                 return SqlHelper.ExecuteScalar(connectionString, CommandType.StoredProcedure, spName);
2218             }
2219         }
2220 
2221         /// <summary> 
2222         /// 执行指定连接数据库连接对象的存储过程,使用DataRow做为参数值,返回结果集中的第一行第一列. 
2223         /// </summary> 
2224         /// <param name="connection">一个有效的数据库连接对象</param> 
2225         /// <param name="spName">存储过程名称</param> 
2226         /// <param name="dataRow">使用DataRow作为参数值</param> 
2227         /// <returns>返回结果集中的第一行第一列</returns> 
2228         public static object ExecuteScalarTypedParams(SqlConnection connection, String spName, DataRow dataRow)
2229         {
2230             if (connection == null) throw new ArgumentNullException("connection");
2231             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
2232 
2233             // 如果row有值,存储过程必须初始化. 
2234             if (dataRow != null && dataRow.ItemArray.Length > 0)
2235             {
2236                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
2237                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
2238 
2239                 // 分配参数值 
2240                 AssignParameterValues(commandParameters, dataRow);
2241 
2242                 return SqlHelper.ExecuteScalar(connection, CommandType.StoredProcedure, spName, commandParameters);
2243             }
2244             else
2245             {
2246                 return SqlHelper.ExecuteScalar(connection, CommandType.StoredProcedure, spName);
2247             }
2248         }
2249 
2250         /// <summary> 
2251         /// 执行指定连接数据库事务的存储过程,使用DataRow做为参数值,返回结果集中的第一行第一列. 
2252         /// </summary> 
2253         /// <param name="transaction">一个有效的连接事务 object</param> 
2254         /// <param name="spName">存储过程名称</param> 
2255         /// <param name="dataRow">使用DataRow作为参数值</param> 
2256         /// <returns>返回结果集中的第一行第一列</returns> 
2257         public static object ExecuteScalarTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
2258         {
2259             if (transaction == null) throw new ArgumentNullException("transaction");
2260             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
2261             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
2262 
2263             // 如果row有值,存储过程必须初始化. 
2264             if (dataRow != null && dataRow.ItemArray.Length > 0)
2265             {
2266                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
2267                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
2268 
2269                 // 分配参数值 
2270                 AssignParameterValues(commandParameters, dataRow);
2271 
2272                 return SqlHelper.ExecuteScalar(transaction, CommandType.StoredProcedure, spName, commandParameters);
2273             }
2274             else
2275             {
2276                 return SqlHelper.ExecuteScalar(transaction, CommandType.StoredProcedure, spName);
2277             }
2278         }
2279         #endregion
2280 
2281         #region ExecuteXmlReaderTypedParams 类型化参数(DataRow)
2282         /// <summary> 
2283         /// 执行指定连接数据库连接对象的存储过程,使用DataRow做为参数值,返回XmlReader类型的结果集. 
2284         /// </summary> 
2285         /// <param name="connection">一个有效的数据库连接对象</param> 
2286         /// <param name="spName">存储过程名称</param> 
2287         /// <param name="dataRow">使用DataRow作为参数值</param> 
2288         /// <returns>返回XmlReader结果集对象.</returns> 
2289         public static XmlReader ExecuteXmlReaderTypedParams(SqlConnection connection, String spName, DataRow dataRow)
2290         {
2291             if (connection == null) throw new ArgumentNullException("connection");
2292             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
2293 
2294             // 如果row有值,存储过程必须初始化. 
2295             if (dataRow != null && dataRow.ItemArray.Length > 0)
2296             {
2297                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
2298                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);
2299 
2300                 // 分配参数值 
2301                 AssignParameterValues(commandParameters, dataRow);
2302 
2303                 return SqlHelper.ExecuteXmlReader(connection, CommandType.StoredProcedure, spName, commandParameters);
2304             }
2305             else
2306             {
2307                 return SqlHelper.ExecuteXmlReader(connection, CommandType.StoredProcedure, spName);
2308             }
2309         }
2310 
2311         /// <summary> 
2312         /// 执行指定连接数据库事务的存储过程,使用DataRow做为参数值,返回XmlReader类型的结果集. 
2313         /// </summary> 
2314         /// <param name="transaction">一个有效的连接事务 object</param> 
2315         /// <param name="spName">存储过程名称</param> 
2316         /// <param name="dataRow">使用DataRow作为参数值</param> 
2317         /// <returns>返回XmlReader结果集对象.</returns> 
2318         public static XmlReader ExecuteXmlReaderTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)
2319         {
2320             if (transaction == null) throw new ArgumentNullException("transaction");
2321             if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
2322             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
2323 
2324             // 如果row有值,存储过程必须初始化. 
2325             if (dataRow != null && dataRow.ItemArray.Length > 0)
2326             {
2327                 // 从缓存中加载存储过程参数,如果缓存中不存在则从数据库中检索参数信息并加载到缓存中. () 
2328                 SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName);
2329 
2330                 // 分配参数值 
2331                 AssignParameterValues(commandParameters, dataRow);
2332 
2333                 return SqlHelper.ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
2334             }
2335             else
2336             {
2337                 return SqlHelper.ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName);
2338             }
2339         }
2340         #endregion
2341 
2342     }
2343 
2344     /// <summary> 
2345     /// SqlHelperParameterCache提供缓存存储过程参数,并能够在运行时从存储过程中探索参数. 
2346     /// </summary> 
2347     public sealed class SqlHelperParameterCache
2348     {
2349         #region 私有方法,字段,构造函数
2350         // 私有构造函数,妨止类被实例化. 
2351         private SqlHelperParameterCache() { }
2352 
2353         // 这个方法要注意 
2354         private static Hashtable paramCache = Hashtable.Synchronized(new Hashtable());
2355 
2356         /// <summary> 
2357         /// 探索运行时的存储过程,返回SqlParameter参数数组. 
2358         /// 初始化参数值为 DBNull.Value. 
2359         /// </summary> 
2360         /// <param name="connection">一个有效的数据库连接</param> 
2361         /// <param name="spName">存储过程名称</param> 
2362         /// <param name="includeReturnValueParameter">是否包含返回值参数</param> 
2363         /// <returns>返回SqlParameter参数数组</returns> 
2364         private static SqlParameter[] DiscoverSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter)
2365         {
2366             if (connection == null) throw new ArgumentNullException("connection");
2367             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
2368 
2369             SqlCommand cmd = new SqlCommand(spName, connection);
2370             cmd.CommandType = CommandType.StoredProcedure;
2371 
2372             connection.Open();
2373             // 检索cmd指定的存储过程的参数信息,并填充到cmd的Parameters参数集中. 
2374             SqlCommandBuilder.DeriveParameters(cmd);
2375             connection.Close();
2376             // 如果不包含返回值参数,将参数集中的每一个参数删除. 
2377             if (!includeReturnValueParameter)
2378             {
2379                 cmd.Parameters.RemoveAt(0);
2380             }
2381 
2382             // 创建参数数组 
2383             SqlParameter[] discoveredParameters = new SqlParameter[cmd.Parameters.Count];
2384             // 将cmd的Parameters参数集复制到discoveredParameters数组. 
2385             cmd.Parameters.CopyTo(discoveredParameters, 0);
2386 
2387             // 初始化参数值为 DBNull.Value. 
2388             foreach (SqlParameter discoveredParameter in discoveredParameters)
2389             {
2390                 discoveredParameter.Value = DBNull.Value;
2391             }
2392             return discoveredParameters;
2393         }
2394 
2395         /// <summary> 
2396         /// SqlParameter参数数组的深层拷贝. 
2397         /// </summary> 
2398         /// <param name="originalParameters">原始参数数组</param> 
2399         /// <returns>返回一个同样的参数数组</returns> 
2400         private static SqlParameter[] CloneParameters(SqlParameter[] originalParameters)
2401         {
2402             SqlParameter[] clonedParameters = new SqlParameter[originalParameters.Length];
2403 
2404             for (int i = 0, j = originalParameters.Length; i < j; i++)
2405             {
2406                 clonedParameters[i] = (SqlParameter)((ICloneable)originalParameters[i]).Clone();
2407             }
2408 
2409             return clonedParameters;
2410         }
2411 
2412         #endregion 私有方法,字段,构造函数结束
2413 
2414         #region 缓存方法
2415 
2416         /// <summary> 
2417         /// 追加参数数组到缓存. 
2418         /// </summary> 
2419         /// <param name="connectionString">一个有效的数据库连接字符串</param> 
2420         /// <param name="commandText">存储过程名或SQL语句</param> 
2421         /// <param name="commandParameters">要缓存的参数数组</param> 
2422         public static void CacheParameterSet(string connectionString, string commandText, params SqlParameter[] commandParameters)
2423         {
2424             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
2425             if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");
2426 
2427             string hashKey = connectionString + ":" + commandText;
2428 
2429             paramCache[hashKey] = commandParameters;
2430         }
2431 
2432         /// <summary> 
2433         /// 从缓存中获取参数数组. 
2434         /// </summary> 
2435         /// <param name="connectionString">一个有效的数据库连接字符</param> 
2436         /// <param name="commandText">存储过程名或SQL语句</param> 
2437         /// <returns>参数数组</returns> 
2438         public static SqlParameter[] GetCachedParameterSet(string connectionString, string commandText)
2439         {
2440             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
2441             if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");
2442 
2443             string hashKey = connectionString + ":" + commandText;
2444 
2445             SqlParameter[] cachedParameters = paramCache[hashKey] as SqlParameter[];
2446             if (cachedParameters == null)
2447             {
2448                 return null;
2449             }
2450             else
2451             {
2452                 return CloneParameters(cachedParameters);
2453             }
2454         }
2455 
2456         #endregion 缓存方法结束
2457 
2458         #region 检索指定的存储过程的参数集
2459 
2460         /// <summary> 
2461         /// 返回指定的存储过程的参数集 
2462         /// </summary> 
2463         /// <remarks> 
2464         /// 这个方法将查询数据库,并将信息存储到缓存. 
2465         /// </remarks> 
2466         /// <param name="connectionString">一个有效的数据库连接字符</param> 
2467         /// <param name="spName">存储过程名</param> 
2468         /// <returns>返回SqlParameter参数数组</returns> 
2469         public static SqlParameter[] GetSpParameterSet(string connectionString, string spName)
2470         {
2471             return GetSpParameterSet(connectionString, spName, false);
2472         }
2473 
2474         /// <summary> 
2475         /// 返回指定的存储过程的参数集 
2476         /// </summary> 
2477         /// <remarks> 
2478         /// 这个方法将查询数据库,并将信息存储到缓存. 
2479         /// </remarks> 
2480         /// <param name="connectionString">一个有效的数据库连接字符.</param> 
2481         /// <param name="spName">存储过程名</param> 
2482         /// <param name="includeReturnValueParameter">是否包含返回值参数</param> 
2483         /// <returns>返回SqlParameter参数数组</returns> 
2484         public static SqlParameter[] GetSpParameterSet(string connectionString, string spName, bool includeReturnValueParameter)
2485         {
2486             if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
2487             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
2488 
2489             using (SqlConnection connection = new SqlConnection(connectionString))
2490             {
2491                 return GetSpParameterSetInternal(connection, spName, includeReturnValueParameter);
2492             }
2493         }
2494 
2495         /// <summary> 
2496         /// [内部]返回指定的存储过程的参数集(使用连接对象). 
2497         /// </summary> 
2498         /// <remarks> 
2499         /// 这个方法将查询数据库,并将信息存储到缓存. 
2500         /// </remarks> 
2501         /// <param name="connection">一个有效的数据库连接字符</param> 
2502         /// <param name="spName">存储过程名</param> 
2503         /// <returns>返回SqlParameter参数数组</returns> 
2504         internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName)
2505         {
2506             return GetSpParameterSet(connection, spName, false);
2507         }
2508 
2509         /// <summary> 
2510         /// [内部]返回指定的存储过程的参数集(使用连接对象) 
2511         /// </summary> 
2512         /// <remarks> 
2513         /// 这个方法将查询数据库,并将信息存储到缓存. 
2514         /// </remarks> 
2515         /// <param name="connection">一个有效的数据库连接对象</param> 
2516         /// <param name="spName">存储过程名</param> 
2517         /// <param name="includeReturnValueParameter"> 
2518         /// 是否包含返回值参数 
2519         /// </param> 
2520         /// <returns>返回SqlParameter参数数组</returns> 
2521         internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter)
2522         {
2523             if (connection == null) throw new ArgumentNullException("connection");
2524             using (SqlConnection clonedConnection = (SqlConnection)((ICloneable)connection).Clone())
2525             {
2526                 return GetSpParameterSetInternal(clonedConnection, spName, includeReturnValueParameter);
2527             }
2528         }
2529 
2530         /// <summary> 
2531         /// [私有]返回指定的存储过程的参数集(使用连接对象) 
2532         /// </summary> 
2533         /// <param name="connection">一个有效的数据库连接对象</param> 
2534         /// <param name="spName">存储过程名</param> 
2535         /// <param name="includeReturnValueParameter">是否包含返回值参数</param> 
2536         /// <returns>返回SqlParameter参数数组</returns> 
2537         private static SqlParameter[] GetSpParameterSetInternal(SqlConnection connection, string spName, bool includeReturnValueParameter)
2538         {
2539             if (connection == null) throw new ArgumentNullException("connection");
2540             if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");
2541 
2542             string hashKey = connection.ConnectionString + ":" + spName + (includeReturnValueParameter ? ":include ReturnValue Parameter" : "");
2543 
2544             SqlParameter[] cachedParameters;
2545 
2546             cachedParameters = paramCache[hashKey] as SqlParameter[];
2547             if (cachedParameters == null)
2548             {
2549                 SqlParameter[] spParameters = DiscoverSpParameterSet(connection, spName, includeReturnValueParameter);
2550                 paramCache[hashKey] = spParameters;
2551                 cachedParameters = spParameters;
2552             }
2553 
2554             return CloneParameters(cachedParameters);
2555         }
2556 
2557         #endregion 参数集检索结束
2558 
2559     }
2560 }
View Code

 字符串操作类

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Text;
  4 using System.Text.RegularExpressions;
  5 
  6 namespace DotNet.Utilities
  7 {
  8     /// <summary>
  9     /// 字符串操作类
 10     /// 1、GetStrArray(string str, char speater, bool toLower)  把字符串按照分隔符转换成 List
 11     /// 2、GetStrArray(string str) 把字符串转 按照, 分割 换为数据
 12     /// 3、GetArrayStr(List list, string speater) 把 List 按照分隔符组装成 string
 13     /// 4、GetArrayStr(List list)  得到数组列表以逗号分隔的字符串
 14     /// 5、GetArrayValueStr(Dictionary<int, int> list)得到数组列表以逗号分隔的字符串
 15     /// 6、DelLastComma(string str)删除最后结尾的一个逗号
 16     /// 7、DelLastChar(string str, string strchar)删除最后结尾的指定字符后的字符
 17     /// 8、ToSBC(string input)转全角的函数(SBC case)
 18     /// 9、ToDBC(string input)转半角的函数(SBC case)
 19     /// 10、GetSubStringList(string o_str, char sepeater)把字符串按照指定分隔符装成 List 去除重复
 20     /// 11、GetCleanStyle(string StrList, string SplitString)将字符串样式转换为纯字符串
 21     /// 12、GetNewStyle(string StrList, string NewStyle, string SplitString, out string Error)将字符串转换为新样式
 22     /// 13、SplitMulti(string str, string splitstr)分割字符串
 23     /// 14、SqlSafeString(string String, bool IsDel)
 24     /// </summary>
 25     public class StringHelper
 26     {
 27         /// <summary>
 28         /// 把字符串按照分隔符转换成 List
 29         /// </summary>
 30         /// <param name="str">源字符串</param>
 31         /// <param name="speater">分隔符</param>
 32         /// <param name="toLower">是否转换为小写</param>
 33         /// <returns></returns>
 34         public static List<string> GetStrArray(string str, char speater, bool toLower)
 35         {
 36             List<string> list = new List<string>();
 37             string[] ss = str.Split(speater);
 38             foreach (string s in ss)
 39             {
 40                 if (!string.IsNullOrEmpty(s) && s != speater.ToString())
 41                 {
 42                     string strVal = s;
 43                     if (toLower)
 44                     {
 45                         strVal = s.ToLower();
 46                     }
 47                     list.Add(strVal);
 48                 }
 49             }
 50             return list;
 51         }
 52         /// <summary>
 53         /// 把字符串转 按照, 分割 换为数据
 54         /// </summary>
 55         /// <param name="str"></param>
 56         /// <returns></returns>
 57         public static string[] GetStrArray(string str)
 58         {
 59             return str.Split(new Char[] { ',' });
 60         }
 61         /// <summary>
 62         /// 把 List<string> 按照分隔符组装成 string
 63         /// </summary>
 64         /// <param name="list"></param>
 65         /// <param name="speater"></param>
 66         /// <returns></returns>
 67         public static string GetArrayStr(List<string> list, string speater)
 68         {
 69             StringBuilder sb = new StringBuilder();
 70             for (int i = 0; i < list.Count; i++)
 71             {
 72                 if (i == list.Count - 1)
 73                 {
 74                     sb.Append(list[i]);
 75                 }
 76                 else
 77                 {
 78                     sb.Append(list[i]);
 79                     sb.Append(speater);
 80                 }
 81             }
 82             return sb.ToString();
 83         }
 84         /// <summary>
 85         /// 得到数组列表以逗号分隔的字符串
 86         /// </summary>
 87         /// <param name="list"></param>
 88         /// <returns></returns>
 89         public static string GetArrayStr(List<int> list)
 90         {
 91             StringBuilder sb = new StringBuilder();
 92             for (int i = 0; i < list.Count; i++)
 93             {
 94                 if (i == list.Count - 1)
 95                 {
 96                     sb.Append(list[i].ToString());
 97                 }
 98                 else
 99                 {
100                     sb.Append(list[i]);
101                     sb.Append(",");
102                 }
103             }
104             return sb.ToString();
105         }
106         /// <summary>
107         /// 得到数组列表以逗号分隔的字符串
108         /// </summary>
109         /// <param name="list"></param>
110         /// <returns></returns>
111         public static string GetArrayValueStr(Dictionary<int, int> list)
112         {
113             StringBuilder sb = new StringBuilder();
114             foreach (KeyValuePair<int, int> kvp in list)
115             {
116                 sb.Append(kvp.Value + ",");
117             }
118             if (list.Count > 0)
119             {
120                 return DelLastComma(sb.ToString());
121             }
122             else
123             {
124                 return "";
125             }
126         }
127 
128 
129         #region 删除最后一个字符之后的字符
130 
131         /// <summary>
132         /// 删除最后结尾的一个逗号
133         /// </summary>
134         public static string DelLastComma(string str)
135         {
136             return str.Substring(0, str.LastIndexOf(","));
137         }
138 
139         /// <summary>
140         /// 删除最后结尾的指定字符后的字符
141         /// </summary>
142         public static string DelLastChar(string str, string strchar)
143         {
144             return str.Substring(0, str.LastIndexOf(strchar));
145         }
146 
147         #endregion
148 
149 
150 
151 
152         /// <summary>
153         /// 转全角的函数(SBC case)
154         /// </summary>
155         /// <param name="input"></param>
156         /// <returns></returns>
157         public static string ToSBC(string input)
158         {
159             //半角转全角:
160             char[] c = input.ToCharArray();
161             for (int i = 0; i < c.Length; i++)
162             {
163                 if (c[i] == 32)
164                 {
165                     c[i] = (char)12288;
166                     continue;
167                 }
168                 if (c[i] < 127)
169                     c[i] = (char)(c[i] + 65248);
170             }
171             return new string(c);
172         }
173 
174         /// <summary>
175         ///  转半角的函数(SBC case)
176         /// </summary>
177         /// <param name="input">输入</param>
178         /// <returns></returns>
179         public static string ToDBC(string input)
180         {
181             char[] c = input.ToCharArray();
182             for (int i = 0; i < c.Length; i++)
183             {
184                 if (c[i] == 12288)
185                 {
186                     c[i] = (char)32;
187                     continue;
188                 }
189                 if (c[i] > 65280 && c[i] < 65375)
190                     c[i] = (char)(c[i] - 65248);
191             }
192             return new string(c);
193         }
194 
195         /// <summary>
196         /// 把字符串按照指定分隔符装成 List 去除重复
197         /// </summary>
198         /// <param name="o_str"></param>
199         /// <param name="sepeater"></param>
200         /// <returns></returns>
201         public static List<string> GetSubStringList(string o_str, char sepeater)
202         {
203             List<string> list = new List<string>();
204             string[] ss = o_str.Split(sepeater);
205             foreach (string s in ss)
206             {
207                 if (!string.IsNullOrEmpty(s) && s != sepeater.ToString())
208                 {
209                     list.Add(s);
210                 }
211             }
212             return list;
213         }
214 
215 
216         #region 将字符串样式转换为纯字符串
217         /// <summary>
218         ///  将字符串样式转换为纯字符串
219         /// </summary>
220         /// <param name="StrList"></param>
221         /// <param name="SplitString"></param>
222         /// <returns></returns>
223         public static string GetCleanStyle(string StrList, string SplitString)
224         {
225             string RetrunValue = "";
226             //如果为空,返回空值
227             if (StrList == null)
228             {
229                 RetrunValue = "";
230             }
231             else
232             {
233                 //返回去掉分隔符
234                 string NewString = "";
235                 NewString = StrList.Replace(SplitString, "");
236                 RetrunValue = NewString;
237             }
238             return RetrunValue;
239         }
240         #endregion
241 
242         #region 将字符串转换为新样式
243         /// <summary>
244         /// 将字符串转换为新样式
245         /// </summary>
246         /// <param name="StrList"></param>
247         /// <param name="NewStyle"></param>
248         /// <param name="SplitString"></param>
249         /// <param name="Error"></param>
250         /// <returns></returns>
251         public static string GetNewStyle(string StrList, string NewStyle, string SplitString, out string Error)
252         {
253             string ReturnValue = "";
254             //如果输入空值,返回空,并给出错误提示
255             if (StrList == null)
256             {
257                 ReturnValue = "";
258                 Error = "请输入需要划分格式的字符串";
259             }
260             else
261             {
262                 //检查传入的字符串长度和样式是否匹配,如果不匹配,则说明使用错误。给出错误信息并返回空值
263                 int strListLength = StrList.Length;
264                 int NewStyleLength = GetCleanStyle(NewStyle, SplitString).Length;
265                 if (strListLength != NewStyleLength)
266                 {
267                     ReturnValue = "";
268                     Error = "样式格式的长度与输入的字符长度不符,请重新输入";
269                 }
270                 else
271                 {
272                     //检查新样式中分隔符的位置
273                     string Lengstr = "";
274                     for (int i = 0; i < NewStyle.Length; i++)
275                     {
276                         if (NewStyle.Substring(i, 1) == SplitString)
277                         {
278                             Lengstr = Lengstr + "," + i;
279                         }
280                     }
281                     if (Lengstr != "")
282                     {
283                         Lengstr = Lengstr.Substring(1);
284                     }
285                     //将分隔符放在新样式中的位置
286                     string[] str = Lengstr.Split(',');
287                     foreach (string bb in str)
288                     {
289                         StrList = StrList.Insert(int.Parse(bb), SplitString);
290                     }
291                     //给出最后的结果
292                     ReturnValue = StrList;
293                     //因为是正常的输出,没有错误
294                     Error = "";
295                 }
296             }
297             return ReturnValue;
298         }
299         #endregion
300 
301         /// <summary>
302         /// 分割字符串
303         /// </summary>
304         /// <param name="str"></param>
305         /// <param name="splitstr"></param>
306         /// <returns></returns>
307         public static string[] SplitMulti(string str, string splitstr)
308         {
309             string[] strArray = null;
310             if ((str != null) && (str != ""))
311             {
312                 strArray = new Regex(splitstr).Split(str);
313             }
314             return strArray;
315         }
316         public static string SqlSafeString(string String, bool IsDel)
317         {
318             if (IsDel)
319             {
320                 String = String.Replace("'", "");
321                 String = String.Replace("\"", "");
322                 return String;
323             }
324             String = String.Replace("'", "&#39;");
325             String = String.Replace("\"", "&#34;");
326             return String;
327         }
328 
329         #region 获取正确的Id,如果不是正整数,返回0
330         /// <summary>
331         /// 获取正确的Id,如果不是正整数,返回0
332         /// </summary>
333         /// <param name="_value"></param>
334         /// <returns>返回正确的整数ID,失败返回0</returns>
335         public static int StrToId(string _value)
336         {
337             if (IsNumberId(_value))
338                 return int.Parse(_value);
339             else
340                 return 0;
341         }
342         #endregion
343         #region 检查一个字符串是否是纯数字构成的,一般用于查询字符串参数的有效性验证。
344         /// <summary>
345         /// 检查一个字符串是否是纯数字构成的,一般用于查询字符串参数的有效性验证。(0除外)
346         /// </summary>
347         /// <param name="_value">需验证的字符串。。</param>
348         /// <returns>是否合法的bool值。</returns>
349         public static bool IsNumberId(string _value)
350         {
351             return QuickValidate("^[1-9]*[0-9]*$", _value);
352         }
353         #endregion
354         #region 快速验证一个字符串是否符合指定的正则表达式。
355         /// <summary>
356         /// 快速验证一个字符串是否符合指定的正则表达式。
357         /// </summary>
358         /// <param name="_express">正则表达式的内容。</param>
359         /// <param name="_value">需验证的字符串。</param>
360         /// <returns>是否合法的bool值。</returns>
361         public static bool QuickValidate(string _express, string _value)
362         {
363             if (_value == null) return false;
364             Regex myRegex = new Regex(_express);
365             if (_value.Length == 0)
366             {
367                 return false;
368             }
369             return myRegex.IsMatch(_value);
370         }
371         #endregion
372 
373 
374         #region 根据配置对指定字符串进行 MD5 加密
375         /// <summary>
376         /// 根据配置对指定字符串进行 MD5 加密
377         /// </summary>
378         /// <param name="s"></param>
379         /// <returns></returns>
380         public static string GetMD5(string s)
381         {
382             //md5加密
383             s = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(s, "md5").ToString();
384 
385             return s.ToLower().Substring(8, 16);
386         }
387         #endregion
388 
389         #region 得到字符串长度,一个汉字长度为2
390         /// <summary>
391         /// 得到字符串长度,一个汉字长度为2
392         /// </summary>
393         /// <param name="inputString">参数字符串</param>
394         /// <returns></returns>
395         public static int StrLength(string inputString)
396         {
397             System.Text.ASCIIEncoding ascii = new System.Text.ASCIIEncoding();
398             int tempLen = 0;
399             byte[] s = ascii.GetBytes(inputString);
400             for (int i = 0; i < s.Length; i++)
401             {
402                 if ((int)s[i] == 63)
403                     tempLen += 2;
404                 else
405                     tempLen += 1;
406             }
407             return tempLen;
408         }
409         #endregion
410 
411         #region 截取指定长度字符串
412         /// <summary>
413         /// 截取指定长度字符串
414         /// </summary>
415         /// <param name="inputString">要处理的字符串</param>
416         /// <param name="len">指定长度</param>
417         /// <returns>返回处理后的字符串</returns>
418         public static string ClipString(string inputString, int len)
419         {
420             bool isShowFix = false;
421             if (len % 2 == 1)
422             {
423                 isShowFix = true;
424                 len--;
425             }
426             System.Text.ASCIIEncoding ascii = new System.Text.ASCIIEncoding();
427             int tempLen = 0;
428             string tempString = "";
429             byte[] s = ascii.GetBytes(inputString);
430             for (int i = 0; i < s.Length; i++)
431             {
432                 if ((int)s[i] == 63)
433                     tempLen += 2;
434                 else
435                     tempLen += 1;
436 
437                 try
438                 {
439                     tempString += inputString.Substring(i, 1);
440                 }
441                 catch
442                 {
443                     break;
444                 }
445 
446                 if (tempLen > len)
447                     break;
448             }
449 
450             byte[] mybyte = System.Text.Encoding.Default.GetBytes(inputString);
451             if (isShowFix && mybyte.Length > len)
452                 tempString += "";
453             return tempString;
454         }
455         #endregion
456 
457 
458 
459         #region HTML转行成TEXT
460         /// <summary>
461         /// HTML转行成TEXT
462         /// </summary>
463         /// <param name="strHtml"></param>
464         /// <returns></returns>
465         public static string HtmlToTxt(string strHtml)
466         {
467             string[] aryReg ={
468             @"<script[^>]*?>.*?</script>",
469             @"<(\/\s*)?!?((\w+:)?\w+)(\w+(\s*=?\s*(([""'])(\\[""'tbnr]|[^\7])*?\7|\w+)|.{0})|\s)*?(\/\s*)?>",
470             @"([\r\n])[\s]+",
471             @"&(quot|#34);",
472             @"&(amp|#38);",
473             @"&(lt|#60);",
474             @"&(gt|#62);", 
475             @"&(nbsp|#160);", 
476             @"&(iexcl|#161);",
477             @"&(cent|#162);",
478             @"&(pound|#163);",
479             @"&(copy|#169);",
480             @"&#(\d+);",
481             @"-->",
482             @"<!--.*\n"
483             };
484 
485             string newReg = aryReg[0];
486             string strOutput = strHtml;
487             for (int i = 0; i < aryReg.Length; i++)
488             {
489                 Regex regex = new Regex(aryReg[i], RegexOptions.IgnoreCase);
490                 strOutput = regex.Replace(strOutput, string.Empty);
491             }
492 
493             strOutput.Replace("<", "");
494             strOutput.Replace(">", "");
495             strOutput.Replace("\r\n", "");
496 
497 
498             return strOutput;
499         }
500         #endregion
501 
502         #region 判断对象是否为空
503         /// <summary>
504         /// 判断对象是否为空,为空返回true
505         /// </summary>
506         /// <typeparam name="T">要验证的对象的类型</typeparam>
507         /// <param name="data">要验证的对象</param>        
508         public static bool IsNullOrEmpty<T>(T data)
509         {
510             //如果为null
511             if (data == null)
512             {
513                 return true;
514             }
515 
516             //如果为""
517             if (data.GetType() == typeof(String))
518             {
519                 if (string.IsNullOrEmpty(data.ToString().Trim()))
520                 {
521                     return true;
522                 }
523             }
524 
525             //如果为DBNull
526             if (data.GetType() == typeof(DBNull))
527             {
528                 return true;
529             }
530 
531             //不为空
532             return false;
533         }
534 
535         /// <summary>
536         /// 判断对象是否为空,为空返回true
537         /// </summary>
538         /// <param name="data">要验证的对象</param>
539         public static bool IsNullOrEmpty(object data)
540         {
541             //如果为null
542             if (data == null)
543             {
544                 return true;
545             }
546 
547             //如果为""
548             if (data.GetType() == typeof(String))
549             {
550                 if (string.IsNullOrEmpty(data.ToString().Trim()))
551                 {
552                     return true;
553                 }
554             }
555 
556             //如果为DBNull
557             if (data.GetType() == typeof(DBNull))
558             {
559                 return true;
560             }
561 
562             //不为空
563             return false;
564         }
565         #endregion
566     }
567 }
字符串操作类

 MD5加密

 #region 加解密
        //MD5加密字符串
        public static string MD5Encrypt(string strText)
        {
            byte[] buffer1 = new MD5CryptoServiceProvider().ComputeHash(Encoding.Unicode.GetBytes(strText));
            StringBuilder builder1 = new StringBuilder();
            foreach (byte num1 in buffer1)
            {
                builder1.Append(num1.ToString("x2").ToLower());
            }
            return builder1.ToString();
        }


        #endregion
View Code

 

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
博文来源广泛,如原作者认为我侵犯知识产权,请尽快给我发邮件 664507902@qq.com联系,我将以第一时间删除相关内容。

posted @ 2015-09-20 22:45  木头园—OOIP  阅读(171)  评论(0)    收藏  举报