sqlHelper類的中文 詳細註釋

lingxyd_0發表於2011-10-01

sqlHelper類的中文 詳細註釋


using System;

using System.Data;

using System.Xml;

using System.Data.SqlClient;

using System.Collections;



namespace Book.DAL

{

    /// <summary>

    /// SqlServer資料訪問幫助類

    /// </summary>

    public sealed class SqlHelper

    {

        #region 私有建構函式和方法



        private SqlHelper() {}



        /// <summary>

        /// 將SqlParameter引數陣列(引數值)分配給SqlCommand命令.

        /// 這個方法將給任何一個引數分配DBNull.Value;

        /// 該操作將阻止預設值的使用.

        /// </summary>

        /// <param name="command">命令名</param>

        /// <param name="commandParameters">SqlParameters陣列</param>

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

        {

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

            if( commandParameters != null )

            {

                foreach (SqlParameter p in commandParameters)

                {

                    if( p != null )

                    {

                        // 檢查未分配值的輸出引數,將其分配以DBNull.Value.

                        if ( ( p.Direction == ParameterDirection.InputOutput || p.Direction == ParameterDirection.Input ) && 

                            (p.Value == null))

                        {

                            p.Value = DBNull.Value;

                        }

                        command.Parameters.Add(p);

                    }

                }

            }

        }



        /// <summary>

        /// 將DataRow型別的列值分配到SqlParameter引數陣列.

        /// </summary>

        /// <param name="commandParameters">要分配值的SqlParameter引數陣列</param>

        /// <param name="dataRow">將要分配給儲存過程引數的DataRow</param>

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

        {

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

            {

                return;

            }



            int i = 0;

            // 設定引數值

            foreach(SqlParameter commandParameter in commandParameters)

            {

                // 建立引數名稱,如果不存在,只丟擲一個異常.

                if( commandParameter.ParameterName == null || 

                    commandParameter.ParameterName.Length <= 1 )

                    throw new Exception( 

                        string.Format("請提供引數{0}一個有效的名稱{1}.", i, commandParameter.ParameterName ) );

                // 從dataRow的表中獲取為引數陣列中陣列名稱的列的索引.

                // 如果存在和引數名稱相同的列,則將列值賦給當前名稱的引數.

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

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

                i++;

            }

        }



        /// <summary>

        /// 將一個物件陣列分配給SqlParameter引數陣列.

        /// </summary>

        /// <param name="commandParameters">要分配值的SqlParameter引數陣列</param>

        /// <param name="parameterValues">將要分配給儲存過程引數的物件陣列</param>

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

        {

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

            {

                return;

            }



            // 確保物件陣列個數與引數個數匹配,如果不匹配,丟擲一個異常.

            if (commandParameters.Length != parameterValues.Length)

            {

                throw new ArgumentException("引數值個數與引數不匹配.");

            }



            // 給引數賦值

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

            {

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

                if (parameterValues[i] is IDbDataParameter)

                {

                    IDbDataParameter paramInstance = (IDbDataParameter)parameterValues[i];

                    if( paramInstance.Value == null )

                    {

                        commandParameters[i].Value = DBNull.Value; 

                    }

                    else

                    {

                        commandParameters[i].Value = paramInstance.Value;

                    }

                }

                else if (parameterValues[i] == null)

                {

                    commandParameters[i].Value = DBNull.Value;

                }

                else

                {

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

                }

            }

        }



        /// <summary>

        /// 預處理使用者提供的命令,資料庫連線/事務/命令型別/引數

        /// </summary>

        /// <param name="command">要處理的SqlCommand</param>

        /// <param name="connection">資料庫連線</param>

        /// <param name="transaction">一個有效的事務或者是null值</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字, 其它.)</param>

        /// <param name="commandText">儲存過程名或都T-SQL命令文字</param>

        /// <param name="commandParameters">和命令相關聯的SqlParameter引數陣列,如果沒有引數為'null'</param>

        /// <param name="mustCloseConnection"><c>true</c> 如果連線是開啟的,則為true,其它情況下為false.</param>

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

        {

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

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



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

            if (connection.State != ConnectionState.Open)

            {

                mustCloseConnection = true;

                connection.Open();

            }

            else

            {

                mustCloseConnection = false;

            }



            // 給命令分配一個資料庫連線.

            command.Connection = connection;



            // 設定命令文字(儲存過程名或SQL語句)

            command.CommandText = commandText;



            // 分配事務

            if (transaction != null)

            {

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

                command.Transaction = transaction;

            }



            // 設定命令型別.

            command.CommandType = commandType;



            // 分配命令引數

            if (commandParameters != null)

            {

                AttachParameters(command, commandParameters);

            }

            return;

        }



        #endregion 私有建構函式和方法結束



        #region ExecuteNonQuery命令



        /// <summary>

        /// 執行指定連線字串,型別的SqlCommand.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字, 其它.)</param>

        /// <param name="commandText">儲存過程名稱或SQL語句</param>

        /// <returns>返回命令影響的行數</returns>

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

        {

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

        }



        /// <summary>

        /// 執行指定連線字串,型別的SqlCommand.如果沒有提供引數,不返回結果.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字, 其它.)</param>

        /// <param name="commandText">儲存過程名稱或SQL語句</param>

        /// <param name="commandParameters">SqlParameter引數陣列</param>

        /// <returns>返回命令影響的行數</returns>

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

        {

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



            using (SqlConnection connection = new SqlConnection(connectionString))

            {

                connection.Open();



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

            }

        }



        /// <summary>

        /// 執行指定連線字串的儲存過程,將物件陣列的值賦給儲存過程引數,

        /// 此方法需要在引數快取方法中探索引數並生成引數.

        /// </summary>

        /// <remarks>

        /// 這個方法沒有提供訪問輸出引數和返回值.

        /// 示例:  

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串/param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="parameterValues">分配到儲存過程輸入引數的物件陣列</param>

        /// <returns>返回受影響的行數</returns>

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

        {

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

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



            // 如果存在引數值

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

            {

                // 從探索儲存過程引數(載入到快取)並分配給儲存過程引數陣列.

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



                // 給儲存過程引數賦值

                AssignParameterValues(commandParameters, parameterValues);



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

            }

            else 

            {

                // 沒有引數情況下

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

            }

        }



        /// <summary>

        /// 執行指定資料庫連線物件的命令 

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="commandType">命令型別(儲存過程,命令文字或其它.)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <returns>返回影響的行數</returns>

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

        {

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

        }



        /// <summary>

        /// 執行指定資料庫連線物件的命令

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="commandType">命令型別(儲存過程,命令文字或其它.)</param>

        /// <param name="commandText">T儲存過程名稱或T-SQL語句</param>

        /// <param name="commandParameters">SqlParamter引數陣列</param>

        /// <returns>返回影響的行數</returns>

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

        {    

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



            // 建立SqlCommand命令,並進行預處理

            SqlCommand cmd = new SqlCommand();

            bool mustCloseConnection = false;

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

            

            // Finally, execute the command

            int retval = cmd.ExecuteNonQuery();

            

            // 清除引數,以便再次使用.

            cmd.Parameters.Clear();

            if( mustCloseConnection )

                connection.Close();

            return retval;

        }



        /// <summary>

        /// 執行指定資料庫連線物件的命令,將物件陣列的值賦給儲存過程引數.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸出引數和返回值

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="spName">儲存過程名</param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        /// <returns>返回影響的行數</returns>

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

        {

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

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



            // 如果有引數值

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

            {

                // 從快取中載入儲存過程引數

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



                // 給儲存過程分配引數值

                AssignParameterValues(commandParameters, parameterValues);



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

            }

            else 

            {

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

            }

        }



        /// <summary>

        /// 執行帶事務的SqlCommand.

        /// </summary>

        /// <remarks>

        /// 示例.:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的資料庫連線物件</param>

        /// <param name="commandType">命令型別(儲存過程,命令文字或其它.)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <returns>返回影響的行數/returns>

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

        {

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

        }



        /// <summary>

        /// 執行帶事務的SqlCommand(指定引數).

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的資料庫連線物件</param>

        /// <param name="commandType">命令型別(儲存過程,命令文字或其它.)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <param name="commandParameters">SqlParamter引數陣列</param>

        /// <returns>返回影響的行數</returns>

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

        {

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

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



            // 預處理

            SqlCommand cmd = new SqlCommand();

            bool mustCloseConnection = false;

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

                

            // 執行

            int retval = cmd.ExecuteNonQuery();

                

            // 清除引數集,以便再次使用.

            cmd.Parameters.Clear();

            return retval;

        }



        /// <summary>

        /// 執行帶事務的SqlCommand(指定引數值).

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸出引數和返回值

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的資料庫連線物件</param>

        /// <param name="spName">儲存過程名</param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        /// <returns>返回受影響的行數</returns>

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

        {

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

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

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



            // 如果有引數值

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

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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



                // 給儲存過程引數賦值

                AssignParameterValues(commandParameters, parameterValues);



                // 呼叫過載方法

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

            }

            else 

            {

                // 沒有引數值

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

            }

        }



        #endregion ExecuteNonQuery方法結束



        #region ExecuteDataset方法



        /// <summary>

        /// 執行指定資料庫連線字串的命令,返回DataSet.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <returns>返回一個包含結果集的DataSet</returns>

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

        {

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

        }



        /// <summary>

        /// 執行指定資料庫連線字串的命令,返回DataSet.

        /// </summary>

        /// <remarks>

        /// 示例: 

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <param name="commandParameters">SqlParamters引數陣列</param>

        /// <returns>返回一個包含結果集的DataSet</returns>

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

        {

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



            // 建立並開啟資料庫連線物件,操作完成釋放物件.

            using (SqlConnection connection = new SqlConnection(connectionString))

            {

                connection.Open();



                // 呼叫指定資料庫連線字串過載方法.

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

            }

        }



        /// <summary>

        /// 執行指定資料庫連線字串的命令,直接提供引數值,返回DataSet.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸出引數和返回值.

        /// 示例: 

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="spName">儲存過程名</param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        /// <returns>返回一個包含結果集的DataSet</returns>

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

        {

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

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

            

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

            {

                // 從快取中檢索儲存過程引數

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



                // 給儲存過程引數分配值

                AssignParameterValues(commandParameters, parameterValues);



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

            }

            else 

            {

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

            }

        }



        /// <summary>

        /// 執行指定資料庫連線物件的命令,返回DataSet.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名或T-SQL語句</param>

        /// <returns>返回一個包含結果集的DataSet</returns>

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

        {

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

        }

        

        /// <summary>

        /// 執行指定資料庫連線物件的命令,指定儲存過程引數,返回DataSet.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名或T-SQL語句</param>

        /// <param name="commandParameters">SqlParamter引數陣列</param>

        /// <returns>返回一個包含結果集的DataSet</returns>

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

        {

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



            // 預處理

            SqlCommand cmd = new SqlCommand();

            bool mustCloseConnection = false;

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

                

            // 建立SqlDataAdapter和DataSet.

            using( SqlDataAdapter da = new SqlDataAdapter(cmd) )

            {

                DataSet ds = new DataSet();



                // 填充DataSet.

                da.Fill(ds);

                

                cmd.Parameters.Clear();



                if( mustCloseConnection )

                    connection.Close();



                return ds;

            }    

        }

        

        /// <summary>

        /// 執行指定資料庫連線物件的命令,指定引數值,返回DataSet.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸入引數和返回值.

        /// 示例.:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="spName">儲存過程名</param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        /// <returns>返回一個包含結果集的DataSet</returns>

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

        {

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

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



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

            {

                // 比快取中載入儲存過程引數

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



                // 給儲存過程引數分配值

                AssignParameterValues(commandParameters, parameterValues);



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

            }

            else 

            {

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

            }

        }



        /// <summary>

        /// 執行指定事務的命令,返回DataSet.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">事務</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名或T-SQL語句</param>

        /// <returns>返回一個包含結果集的DataSet</returns>

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

        {

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

        }

        

        /// <summary>

        /// 執行指定事務的命令,指定引數,返回DataSet.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">事務</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名或T-SQL語句</param>

        /// <param name="commandParameters">SqlParamter引數陣列</param>

        /// <returns>返回一個包含結果集的DataSet</returns>

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

        {

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

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



            // 預處理

            SqlCommand cmd = new SqlCommand();

            bool mustCloseConnection = false;

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

                

            // 建立 DataAdapter & DataSet

            using( SqlDataAdapter da = new SqlDataAdapter(cmd) )

            {

                DataSet ds = new DataSet();

                da.Fill(ds);

                cmd.Parameters.Clear();

                return ds;

            }    

        }

        

        /// <summary>

        /// 執行指定事務的命令,指定引數值,返回DataSet.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸入引數和返回值.

        /// 示例.:  

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

        /// </remarks>

        /// <param name="transaction">事務</param>

        /// <param name="spName">儲存過程名</param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        /// <returns>返回一個包含結果集的DataSet</returns>

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

        {

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

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

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

            

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

            {

                // 從快取中載入儲存過程引數

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



                // 給儲存過程引數分配值

                AssignParameterValues(commandParameters, parameterValues);



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

            }

            else 

            {

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

            }

        }



        #endregion ExecuteDataset資料集命令結束

        

        #region ExecuteReader 資料閱讀器



        /// <summary>

        /// 列舉,標識資料庫連線是由SqlHelper提供還是由呼叫者提供

        /// </summary>

        private enum SqlConnectionOwnership    

        {

            /// <summary>由SqlHelper提供連線</summary>

            Internal, 

            /// <summary>由呼叫者提供連線</summary>

            External

        }



        /// <summary>

        /// 執行指定資料庫連線物件的資料閱讀器.

        /// </summary>

        /// <remarks>

        /// 如果是SqlHelper開啟連線,當連線關閉DataReader也將關閉.

        /// 如果是呼叫都開啟連線,DataReader由呼叫都管理.

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="transaction">一個有效的事務,或者為 'null'</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名或T-SQL語句</param>

        /// <param name="commandParameters">SqlParameters引數陣列,如果沒有引數則為'null'</param>

        /// <param name="connectionOwnership">標識資料庫連線物件是由呼叫者提供還是由SqlHelper提供</param>

        /// <returns>返回包含結果集的SqlDataReader</returns>

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

        {    

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



            bool mustCloseConnection = false;

            // 建立命令

            SqlCommand cmd = new SqlCommand();

            try

            {

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

            

                // 建立資料閱讀器

                SqlDataReader dataReader;



                if (connectionOwnership == SqlConnectionOwnership.External)

                {

                    dataReader = cmd.ExecuteReader();

                }

                else

                {

                    dataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);

                }

            

                // 清除引數,以便再次使用..

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

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

                // then the SqlReader can磘 set its values. 

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

                bool canClear = true;

                foreach(SqlParameter commandParameter in cmd.Parameters)

                {

                    if (commandParameter.Direction != ParameterDirection.Input)

                        canClear = false;

                }

            

                if (canClear)

                {

                    cmd.Parameters.Clear();

                }



                return dataReader;

            }

            catch

            {

                if( mustCloseConnection )

                    connection.Close();

                throw;

            }

        }



        /// <summary>

        /// 執行指定資料庫連線字串的資料閱讀器.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名或T-SQL語句</param>

        /// <returns>返回包含結果集的SqlDataReader</returns>

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

        {

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

        }



        /// <summary>

        /// 執行指定資料庫連線字串的資料閱讀器,指定引數.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名或T-SQL語句</param>

        /// <param name="commandParameters">SqlParamter引數陣列(new SqlParameter("@prodid", 24))</param>

        /// <returns>返回包含結果集的SqlDataReader</returns>

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

        {

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

            SqlConnection connection = null;

            try

            {

                connection = new SqlConnection(connectionString);

                connection.Open();



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

            }

            catch

            {

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

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

                throw;

            }

            

        }



        /// <summary>

        /// 執行指定資料庫連線字串的資料閱讀器,指定引數值.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸出引數和返回值引數.

        /// 示例:  

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="spName">儲存過程名</param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        /// <returns>返回包含結果集的SqlDataReader</returns>

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

        {

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

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

            

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

            {

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



                AssignParameterValues(commandParameters, parameterValues);



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

            }

            else 

            {

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

            }

        }



        /// <summary>

        /// 執行指定資料庫連線物件的資料閱讀器.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名或T-SQL語句</param>

        /// <returns>返回包含結果集的SqlDataReader</returns>

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

        {

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

        }



        /// <summary>

        /// [呼叫者方式]執行指定資料庫連線物件的資料閱讀器,指定引數.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandParameters">SqlParamter引數陣列</param>

        /// <returns>返回包含結果集的SqlDataReader</returns>

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

        {

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

        }



        /// <summary>

        /// [呼叫者方式]執行指定資料庫連線物件的資料閱讀器,指定引數值.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸出引數和返回值引數.

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="spName">T儲存過程名</param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        /// <returns>返回包含結果集的SqlDataReader</returns>

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

        {

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

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



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

            {

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



                AssignParameterValues(commandParameters, parameterValues);



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

            }

            else 

            {

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

            }

        }



        /// <summary>

        /// [呼叫者方式]執行指定資料庫事務的資料閱讀器,指定引數值.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的連線事務</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <returns>返回包含結果集的SqlDataReader</returns>

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

        {

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

        }



        /// <summary>

        /// [呼叫者方式]執行指定資料庫事務的資料閱讀器,指定引數.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的連線事務</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <param name="commandParameters">分配給命令的SqlParamter引數陣列</param>

        /// <returns>返回包含結果集的SqlDataReader</returns>

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

        {

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

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



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

        }



        /// <summary>

        /// [呼叫者方式]執行指定資料庫事務的資料閱讀器,指定引數值.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸出引數和返回值引數.

        /// 

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的連線事務</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        /// <returns>返回包含結果集的SqlDataReader</returns>

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

        {

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

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

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



            // 如果有引數值

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

            {

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



                AssignParameterValues(commandParameters, parameterValues);



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

            }

            else 

            {

                // 沒有引數值

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

            }

        }



        #endregion ExecuteReader資料閱讀器



        #region ExecuteScalar 返回結果集中的第一行第一列

        

        /// <summary>

        /// 執行指定資料庫連線字串的命令,返回結果集中的第一行第一列.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <returns>返回結果集中的第一行第一列</returns>

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

        {

            // 執行引數為空的方法

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

        }



        /// <summary>

        /// 執行指定資料庫連線字串的命令,指定引數,返回結果集中的第一行第一列.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <param name="commandParameters">分配給命令的SqlParamter引數陣列</param>

        /// <returns>返回結果集中的第一行第一列</returns>

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

        {

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

            // 建立並開啟資料庫連線物件,操作完成釋放物件.

            using (SqlConnection connection = new SqlConnection(connectionString))

            {

                connection.Open();



                // 呼叫指定資料庫連線字串過載方法.

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

            }

        }



        /// <summary>

        /// 執行指定資料庫連線字串的命令,指定引數值,返回結果集中的第一行第一列.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸出引數和返回值引數.

        /// 

        /// 示例:  

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        /// <returns>返回結果集中的第一行第一列</returns>

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

        {

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

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

            

            // 如果有引數值

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

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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



                // 給儲存過程引數賦值

                AssignParameterValues(commandParameters, parameterValues);



                // 呼叫過載方法

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

            }

            else 

            {

                // 沒有引數值

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

            }

        }



        /// <summary>

        /// 執行指定資料庫連線物件的命令,返回結果集中的第一行第一列.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <returns>返回結果集中的第一行第一列</returns>

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

        {

            // 執行引數為空的方法

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

        }



        /// <summary>

        /// 執行指定資料庫連線物件的命令,指定引數,返回結果集中的第一行第一列.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <param name="commandParameters">分配給命令的SqlParamter引數陣列</param>

        /// <returns>返回結果集中的第一行第一列</returns>

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

        {

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



            // 建立SqlCommand命令,並進行預處理

            SqlCommand cmd = new SqlCommand();



            bool mustCloseConnection = false;

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

                

            // 執行SqlCommand命令,並返回結果.

            object retval = cmd.ExecuteScalar();

                

            // 清除引數,以便再次使用.

            cmd.Parameters.Clear();



            if( mustCloseConnection )

                connection.Close();



            return retval;

        }



        /// <summary>

        /// 執行指定資料庫連線物件的命令,指定引數值,返回結果集中的第一行第一列.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸出引數和返回值引數.

        /// 

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        /// <returns>返回結果集中的第一行第一列</returns>

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

        {

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

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



            // 如果有引數值

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

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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



                // 給儲存過程引數賦值

                AssignParameterValues(commandParameters, parameterValues);



                // 呼叫過載方法

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

            }

            else 

            {

                // 沒有引數值

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

            }

        }



        /// <summary>

        /// 執行指定資料庫事務的命令,返回結果集中的第一行第一列.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的連線事務</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <returns>返回結果集中的第一行第一列</returns>

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

        {

            // 執行引數為空的方法

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

        }



        /// <summary>

        /// 執行指定資料庫事務的命令,指定引數,返回結果集中的第一行第一列.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的連線事務</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <param name="commandParameters">分配給命令的SqlParamter引數陣列</param>

        /// <returns>返回結果集中的第一行第一列</returns>

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

        {

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

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



            // 建立SqlCommand命令,並進行預處理

            SqlCommand cmd = new SqlCommand();

            bool mustCloseConnection = false;

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

                

            // 執行SqlCommand命令,並返回結果.

            object retval = cmd.ExecuteScalar();

                

            // 清除引數,以便再次使用.

            cmd.Parameters.Clear();

            return retval;

        }



        /// <summary>

        /// 執行指定資料庫事務的命令,指定引數值,返回結果集中的第一行第一列.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸出引數和返回值引數.

        /// 

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的連線事務</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        /// <returns>返回結果集中的第一行第一列</returns>

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

        {

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

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

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



            // 如果有引數值

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

            {

                // PPull the parameters for this stored procedure from the parameter cache ()

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



                // 給儲存過程引數賦值

                AssignParameterValues(commandParameters, parameterValues);



                // 呼叫過載方法

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

            }

            else 

            {

                // 沒有引數值

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

            }

        }



        #endregion ExecuteScalar    



        #region ExecuteXmlReader XML閱讀器

        /// <summary>

        /// 執行指定資料庫連線物件的SqlCommand命令,併產生一個XmlReader物件做為結果集返回.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句 using "FOR XML AUTO"</param>

        /// <returns>返回XmlReader結果集物件.</returns>

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

        {

            // 執行引數為空的方法

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

        }



        /// <summary>

        /// 執行指定資料庫連線物件的SqlCommand命令,併產生一個XmlReader物件做為結果集返回,指定引數.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句 using "FOR XML AUTO"</param>

        /// <param name="commandParameters">分配給命令的SqlParamter引數陣列</param>

        /// <returns>返回XmlReader結果集物件.</returns>

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

        {

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



            bool mustCloseConnection = false;

            // 建立SqlCommand命令,並進行預處理

            SqlCommand cmd = new SqlCommand();

            try

            {

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

            

                // 執行命令

                XmlReader retval = cmd.ExecuteXmlReader();

            

                // 清除引數,以便再次使用.

                cmd.Parameters.Clear();



                return retval;

            }

            catch

            {    

                if( mustCloseConnection )

                    connection.Close();

                throw;

            }

        }



        /// <summary>

        /// 執行指定資料庫連線物件的SqlCommand命令,併產生一個XmlReader物件做為結果集返回,指定引數值.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸出引數和返回值引數.

        /// 

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="spName">儲存過程名稱 using "FOR XML AUTO"</param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        /// <returns>返回XmlReader結果集物件.</returns>

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

        {

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

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



            // 如果有引數值

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

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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



                // 給儲存過程引數賦值

                AssignParameterValues(commandParameters, parameterValues);



                // 呼叫過載方法

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

            }

            else 

            {

                // 沒有引數值

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

            }

        }



        /// <summary>

        /// 執行指定資料庫事務的SqlCommand命令,併產生一個XmlReader物件做為結果集返回.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的連線事務</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句 using "FOR XML AUTO"</param>

        /// <returns>返回XmlReader結果集物件.</returns>

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

        {

            // 執行引數為空的方法

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

        }



        /// <summary>

        /// 執行指定資料庫事務的SqlCommand命令,併產生一個XmlReader物件做為結果集返回,指定引數.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的連線事務</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句 using "FOR XML AUTO"</param>

        /// <param name="commandParameters">分配給命令的SqlParamter引數陣列</param>

        /// <returns>返回XmlReader結果集物件.</returns>

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

        {

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

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



            // 建立SqlCommand命令,並進行預處理

            SqlCommand cmd = new SqlCommand();

            bool mustCloseConnection = false;

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

            

            // 執行命令

            XmlReader retval = cmd.ExecuteXmlReader();

            

            // 清除引數,以便再次使用.

            cmd.Parameters.Clear();

            return retval;            

        }



        /// <summary>

        /// 執行指定資料庫事務的SqlCommand命令,併產生一個XmlReader物件做為結果集返回,指定引數值.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸出引數和返回值引數.

        /// 

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的連線事務</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        /// <returns>返回一個包含結果集的DataSet.</returns>

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

        {

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

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

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



            // 如果有引數值

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

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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



                // 給儲存過程引數賦值

                AssignParameterValues(commandParameters, parameterValues);



                // 呼叫過載方法

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

            }

            else 

            {

                // 沒有引數值

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

            }

        }



        #endregion ExecuteXmlReader 閱讀器結束



        #region FillDataset 填充資料集

        /// <summary>

        /// 執行指定資料庫連線字串的命令,對映資料表並填充資料集.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <param name="dataSet">要填充結果集的DataSet例項</param>

        /// <param name="tableNames">表對映的資料表陣列

        /// 使用者定義的表名 (可有是實際的表名.)</param>

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

        {

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

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

            

            // 建立並開啟資料庫連線物件,操作完成釋放物件.

            using (SqlConnection connection = new SqlConnection(connectionString))

            {

                connection.Open();



                // 呼叫指定資料庫連線字串過載方法.

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

            }

        }



        /// <summary>

        /// 執行指定資料庫連線字串的命令,對映資料表並填充資料集.指定命令引數.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <param name="commandParameters">分配給命令的SqlParamter引數陣列</param>

        /// <param name="dataSet">要填充結果集的DataSet例項</param>

        /// <param name="tableNames">表對映的資料表陣列

        /// 使用者定義的表名 (可有是實際的表名.)

        /// </param>

        public static void FillDataset(string connectionString, CommandType commandType,

            string commandText, DataSet dataSet, string[] tableNames,

            params SqlParameter[] commandParameters)

        {

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

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

            // 建立並開啟資料庫連線物件,操作完成釋放物件.

            using (SqlConnection connection = new SqlConnection(connectionString))

            {

                connection.Open();



                // 呼叫指定資料庫連線字串過載方法.

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

            }

        }



        /// <summary>

        /// 執行指定資料庫連線字串的命令,對映資料表並填充資料集,指定儲存過程引數值.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸出引數和返回值引數.

        /// 

        /// 示例:  

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

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataSet">要填充結果集的DataSet例項</param>

        /// <param name="tableNames">表對映的資料表陣列

        /// 使用者定義的表名 (可有是實際的表名.)

        /// </param>    

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        public static void FillDataset(string connectionString, string spName,

            DataSet dataSet, string[] tableNames,

            params object[] parameterValues)

        {

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

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

            // 建立並開啟資料庫連線物件,操作完成釋放物件.

            using (SqlConnection connection = new SqlConnection(connectionString))

            {

                connection.Open();



                // 呼叫指定資料庫連線字串過載方法.

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

            }

        }



        /// <summary>

        /// 執行指定資料庫連線物件的命令,對映資料表並填充資料集.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <param name="dataSet">要填充結果集的DataSet例項</param>

        /// <param name="tableNames">表對映的資料表陣列

        /// 使用者定義的表名 (可有是實際的表名.)

        /// </param>    

        public static void FillDataset(SqlConnection connection, CommandType commandType, 

            string commandText, DataSet dataSet, string[] tableNames)

        {

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

        }



        /// <summary>

        /// 執行指定資料庫連線物件的命令,對映資料表並填充資料集,指定引數.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <param name="dataSet">要填充結果集的DataSet例項</param>

        /// <param name="tableNames">表對映的資料表陣列

        /// 使用者定義的表名 (可有是實際的表名.)

        /// </param>

        /// <param name="commandParameters">分配給命令的SqlParamter引數陣列</param>

        public static void FillDataset(SqlConnection connection, CommandType commandType, 

            string commandText, DataSet dataSet, string[] tableNames,

            params SqlParameter[] commandParameters)

        {

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

        }



        /// <summary>

        /// 執行指定資料庫連線物件的命令,對映資料表並填充資料集,指定儲存過程引數值.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸出引數和返回值引數.

        /// 

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataSet">要填充結果集的DataSet例項</param>

        /// <param name="tableNames">表對映的資料表陣列

        /// 使用者定義的表名 (可有是實際的表名.)

        /// </param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        public static void FillDataset(SqlConnection connection, string spName, 

            DataSet dataSet, string[] tableNames,

            params object[] parameterValues)

        {

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

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

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



            // 如果有引數值

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

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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



                // 給儲存過程引數賦值

                AssignParameterValues(commandParameters, parameterValues);



                // 呼叫過載方法

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

            }

            else 

            {

                // 沒有引數值

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

            }    

        }



        /// <summary>

        /// 執行指定資料庫事務的命令,對映資料表並填充資料集.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的連線事務</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <param name="dataSet">要填充結果集的DataSet例項</param>

        /// <param name="tableNames">表對映的資料表陣列

        /// 使用者定義的表名 (可有是實際的表名.)

        /// </param>

        public static void FillDataset(SqlTransaction transaction, CommandType commandType, 

            string commandText,

            DataSet dataSet, string[] tableNames)

        {

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

        }



        /// <summary>

        /// 執行指定資料庫事務的命令,對映資料表並填充資料集,指定引數.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的連線事務</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <param name="dataSet">要填充結果集的DataSet例項</param>

        /// <param name="tableNames">表對映的資料表陣列

        /// 使用者定義的表名 (可有是實際的表名.)

        /// </param>

        /// <param name="commandParameters">分配給命令的SqlParamter引數陣列</param>

        public static void FillDataset(SqlTransaction transaction, CommandType commandType, 

            string commandText, DataSet dataSet, string[] tableNames,

            params SqlParameter[] commandParameters)

        {

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

        }



        /// <summary>

        /// 執行指定資料庫事務的命令,對映資料表並填充資料集,指定儲存過程引數值.

        /// </summary>

        /// <remarks>

        /// 此方法不提供訪問儲存過程輸出引數和返回值引數.

        /// 

        /// 示例:  

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

        /// </remarks>

        /// <param name="transaction">一個有效的連線事務</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataSet">要填充結果集的DataSet例項</param>

        /// <param name="tableNames">表對映的資料表陣列

        /// 使用者定義的表名 (可有是實際的表名.)

        /// </param>

        /// <param name="parameterValues">分配給儲存過程輸入引數的物件陣列</param>

        public static void FillDataset(SqlTransaction transaction, string spName,

            DataSet dataSet, string[] tableNames,

            params object[] parameterValues) 

        {

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

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

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

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



            // 如果有引數值

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

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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



                // 給儲存過程引數賦值

                AssignParameterValues(commandParameters, parameterValues);



                // 呼叫過載方法

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

            }

            else 

            {

                // 沒有引數值

                FillDataset(transaction, CommandType.StoredProcedure, spName, dataSet, tableNames);

            }    

        }



        /// <summary>

        /// [私有方法][內部呼叫]執行指定資料庫連線物件/事務的命令,對映資料表並填充資料集,DataSet/TableNames/SqlParameters.

        /// </summary>

        /// <remarks>

        /// 示例:  

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

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="transaction">一個有效的連線事務</param>

        /// <param name="commandType">命令型別 (儲存過程,命令文字或其它)</param>

        /// <param name="commandText">儲存過程名稱或T-SQL語句</param>

        /// <param name="dataSet">要填充結果集的DataSet例項</param>

        /// <param name="tableNames">表對映的資料表陣列

        /// 使用者定義的表名 (可有是實際的表名.)

        /// </param>

        /// <param name="commandParameters">分配給命令的SqlParamter引數陣列</param>

        private static void FillDataset(SqlConnection connection, SqlTransaction transaction, CommandType commandType, 

            string commandText, DataSet dataSet, string[] tableNames,

            params SqlParameter[] commandParameters)

        {

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

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



            // 建立SqlCommand命令,並進行預處理

            SqlCommand command = new SqlCommand();

            bool mustCloseConnection = false;

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

                

            // 執行命令

            using( SqlDataAdapter dataAdapter = new SqlDataAdapter(command) )

            {

                

                // 追加表對映

                if (tableNames != null && tableNames.Length > 0)

                {

                    string tableName = "Table";

                    for (int index=0; index < tableNames.Length; index++)

                    {

                        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" );

                        dataAdapter.TableMappings.Add(tableName, tableNames[index]);

                        tableName += (index + 1).ToString();

                    }

                }

                

                // 填充資料集使用預設表名稱

                dataAdapter.Fill(dataSet);



                // 清除引數,以便再次使用.

                command.Parameters.Clear();

            }



            if( mustCloseConnection )

                connection.Close();

        }

        #endregion

        

        #region UpdateDataset 更新資料集

        /// <summary>

        /// 執行資料集更新到資料庫,指定inserted, updated, or deleted命令.

        /// </summary>

        /// <remarks>

        /// 示例:  

        ///  UpdateDataset(conn, insertCommand, deleteCommand, updateCommand, dataSet, "Order");

        /// </remarks>

        /// <param name="insertCommand">[追加記錄]一個有效的T-SQL語句或儲存過程</param>

        /// <param name="deleteCommand">[刪除記錄]一個有效的T-SQL語句或儲存過程</param>

        /// <param name="updateCommand">[更新記錄]一個有效的T-SQL語句或儲存過程</param>

        /// <param name="dataSet">要更新到資料庫的DataSet</param>

        /// <param name="tableName">要更新到資料庫的DataTable</param>

        public static void UpdateDataset(SqlCommand insertCommand, SqlCommand deleteCommand, SqlCommand updateCommand, DataSet dataSet, string tableName)

        {

            if( insertCommand == null ) throw new ArgumentNullException( "insertCommand" );

            if( deleteCommand == null ) throw new ArgumentNullException( "deleteCommand" );

            if( updateCommand == null ) throw new ArgumentNullException( "updateCommand" );

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



            // 建立SqlDataAdapter,當操作完成後釋放.

            using (SqlDataAdapter dataAdapter = new SqlDataAdapter())

            {

                // 設定資料介面卡命令

                dataAdapter.UpdateCommand = updateCommand;

                dataAdapter.InsertCommand = insertCommand;

                dataAdapter.DeleteCommand = deleteCommand;



                // 更新資料集改變到資料庫

                dataAdapter.Update (dataSet, tableName); 



                // 提交所有改變到資料集.

                dataSet.AcceptChanges();

            }

        }

        #endregion



        #region CreateCommand 建立一條SqlCommand命令

        /// <summary>

        /// 建立SqlCommand命令,指定資料庫連線物件,儲存過程名和引數.

        /// </summary>

        /// <remarks>

        /// 示例:  

        ///  SqlCommand command = CreateCommand(conn, "AddCustomer", "CustomerID", "CustomerName");

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="sourceColumns">源表的列名稱陣列</param>

        /// <returns>返回SqlCommand命令</returns>

        public static SqlCommand CreateCommand(SqlConnection connection, string spName, params string[] sourceColumns) 

        {

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

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



            // 建立命令

            SqlCommand cmd = new SqlCommand( spName, connection );

            cmd.CommandType = CommandType.StoredProcedure;



            // 如果有引數值

            if ((sourceColumns != null) && (sourceColumns.Length > 0)) 

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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



                // 將源表的列到對映到DataSet命令中.

                for (int index=0; index < sourceColumns.Length; index++)

                    commandParameters[index].SourceColumn = sourceColumns[index];



                // Attach the discovered parameters to the SqlCommand object

                AttachParameters (cmd, commandParameters);

            }



            return cmd;

        }

        #endregion



        #region ExecuteNonQueryTypedParams 型別化引數(DataRow)

        /// <summary>

        /// 執行指定連線資料庫連線字串的儲存過程,使用DataRow做為引數值,返回受影響的行數.

        /// </summary>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataRow">使用DataRow作為引數值</param>

        /// <returns>返回影響的行數</returns>

        public static int ExecuteNonQueryTypedParams(String connectionString, String spName, DataRow dataRow)

        {

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

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

            

            // 如果row有值,儲存過程必須初始化.

            if (dataRow != null && dataRow.ItemArray.Length > 0)

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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

                

                // 分配引數值

                AssignParameterValues(commandParameters, dataRow);

                                

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

            }

            else

            {

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

            }

        }



        /// <summary>

        /// 執行指定連線資料庫連線物件的儲存過程,使用DataRow做為引數值,返回受影響的行數.

        /// </summary>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataRow">使用DataRow作為引數值</param>

        /// <returns>返回影響的行數</returns>

        public static int ExecuteNonQueryTypedParams(SqlConnection connection, String spName, DataRow dataRow)

        {

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

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



            // 如果row有值,儲存過程必須初始化.

            if (dataRow != null && dataRow.ItemArray.Length > 0)

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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

                

                // 分配引數值

                AssignParameterValues(commandParameters, dataRow);

                                

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

            }

            else

            {

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

            }

        }



        /// <summary>

        /// 執行指定連線資料庫事物的儲存過程,使用DataRow做為引數值,返回受影響的行數.

        /// </summary>

        /// <param name="transaction">一個有效的連線事務 object</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataRow">使用DataRow作為引數值</param>

        /// <returns>返回影響的行數</returns>

        public static int ExecuteNonQueryTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)

        {

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

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

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



            // Sf the row has values, the store procedure parameters must be initialized

            if (dataRow != null && dataRow.ItemArray.Length > 0)

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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

                

                // 分配引數值

                AssignParameterValues(commandParameters, dataRow);

                                

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

            }

            else

            {

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

            }

        }

        #endregion



        #region ExecuteDatasetTypedParams 型別化引數(DataRow)

        /// <summary>

        /// 執行指定連線資料庫連線字串的儲存過程,使用DataRow做為引數值,返回DataSet.

        /// </summary>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataRow">使用DataRow作為引數值</param>

        /// <returns>返回一個包含結果集的DataSet.</returns>

        public static DataSet ExecuteDatasetTypedParams(string connectionString, String spName, DataRow dataRow)

        {

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

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



            //如果row有值,儲存過程必須初始化.

            if ( dataRow != null && dataRow.ItemArray.Length > 0)

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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

                

                // 分配引數值

                AssignParameterValues(commandParameters, dataRow);

                

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

            }

            else

            {

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

            }

        }



        /// <summary>

        /// 執行指定連線資料庫連線物件的儲存過程,使用DataRow做為引數值,返回DataSet.

        /// </summary>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataRow">使用DataRow作為引數值</param>

        /// <returns>返回一個包含結果集的DataSet.</returns>

        /// 

        public static DataSet ExecuteDatasetTypedParams(SqlConnection connection, String spName, DataRow dataRow)

        {

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

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



            // 如果row有值,儲存過程必須初始化.

            if( dataRow != null && dataRow.ItemArray.Length > 0)

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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

                

                // 分配引數值

                AssignParameterValues(commandParameters, dataRow);

                

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

            }

            else

            {

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

            }

        }



        /// <summary>

        /// 執行指定連線資料庫事務的儲存過程,使用DataRow做為引數值,返回DataSet.

        /// </summary>

        /// <param name="transaction">一個有效的連線事務 object</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataRow">使用DataRow作為引數值</param>

        /// <returns>返回一個包含結果集的DataSet.</returns>

        public static DataSet ExecuteDatasetTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)

        {

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

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

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



            // 如果row有值,儲存過程必須初始化.

            if( dataRow != null && dataRow.ItemArray.Length > 0)

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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

                

                // 分配引數值

                AssignParameterValues(commandParameters, dataRow);

                

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

            }

            else

            {

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

            }

        }



        #endregion



        #region ExecuteReaderTypedParams 型別化引數(DataRow)

        /// <summary>

        /// 執行指定連線資料庫連線字串的儲存過程,使用DataRow做為引數值,返回DataReader.

        /// </summary>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataRow">使用DataRow作為引數值</param>

        /// <returns>返回包含結果集的SqlDataReader</returns>

        public static SqlDataReader ExecuteReaderTypedParams(String connectionString, String spName, DataRow dataRow)

        {

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

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

            

            // 如果row有值,儲存過程必須初始化.

            if ( dataRow != null && dataRow.ItemArray.Length > 0 )

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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

                

                // 分配引數值

                AssignParameterValues(commandParameters, dataRow);

                

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

            }

            else

            {

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

            }

        }



                

        /// <summary>

        /// 執行指定連線資料庫連線物件的儲存過程,使用DataRow做為引數值,返回DataReader.

        /// </summary>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataRow">使用DataRow作為引數值</param>

        /// <returns>返回包含結果集的SqlDataReader</returns>

        public static SqlDataReader ExecuteReaderTypedParams(SqlConnection connection, String spName, DataRow dataRow)

        {

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

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



            // 如果row有值,儲存過程必須初始化.

            if( dataRow != null && dataRow.ItemArray.Length > 0)

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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

                

                // 分配引數值

                AssignParameterValues(commandParameters, dataRow);

                

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

            }

            else

            {

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

            }

        }

        

        /// <summary>

        /// 執行指定連線資料庫事物的儲存過程,使用DataRow做為引數值,返回DataReader.

        /// </summary>

        /// <param name="transaction">一個有效的連線事務 object</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataRow">使用DataRow作為引數值</param>

        /// <returns>返回包含結果集的SqlDataReader</returns>

        public static SqlDataReader ExecuteReaderTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)

        {

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

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

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



            // 如果row有值,儲存過程必須初始化.

            if( dataRow != null && dataRow.ItemArray.Length > 0 )

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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

                

                // 分配引數值

                AssignParameterValues(commandParameters, dataRow);

                

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

            }

            else

            {

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

            }

        }

        #endregion



        #region ExecuteScalarTypedParams 型別化引數(DataRow)

        /// <summary>

        /// 執行指定連線資料庫連線字串的儲存過程,使用DataRow做為引數值,返回結果集中的第一行第一列.

        /// </summary>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataRow">使用DataRow作為引數值</param>

        /// <returns>返回結果集中的第一行第一列</returns>

        public static object ExecuteScalarTypedParams(String connectionString, String spName, DataRow dataRow)

        {

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

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

            

            // 如果row有值,儲存過程必須初始化.

            if( dataRow != null && dataRow.ItemArray.Length > 0)

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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

                

                // 分配引數值

                AssignParameterValues(commandParameters, dataRow);

                

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

            }

            else

            {

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

            }

        }



        /// <summary>

        /// 執行指定連線資料庫連線物件的儲存過程,使用DataRow做為引數值,返回結果集中的第一行第一列.

        /// </summary>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataRow">使用DataRow作為引數值</param>

        /// <returns>返回結果集中的第一行第一列</returns>

        public static object ExecuteScalarTypedParams(SqlConnection connection, String spName, DataRow dataRow)

        {

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

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



            // 如果row有值,儲存過程必須初始化.

            if( dataRow != null && dataRow.ItemArray.Length > 0)

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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

                

                // 分配引數值

                AssignParameterValues(commandParameters, dataRow);

                

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

            }

            else

            {

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

            }

        }



        /// <summary>

        /// 執行指定連線資料庫事務的儲存過程,使用DataRow做為引數值,返回結果集中的第一行第一列.

        /// </summary>

        /// <param name="transaction">一個有效的連線事務 object</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataRow">使用DataRow作為引數值</param>

        /// <returns>返回結果集中的第一行第一列</returns>

        public static object ExecuteScalarTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)

        {

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

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

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



            // 如果row有值,儲存過程必須初始化.

            if( dataRow != null && dataRow.ItemArray.Length > 0)

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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

                

                // 分配引數值

                AssignParameterValues(commandParameters, dataRow);

                

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

            }

            else

            {

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

            }

        }

        #endregion



        #region ExecuteXmlReaderTypedParams 型別化引數(DataRow)

        /// <summary>

        /// 執行指定連線資料庫連線物件的儲存過程,使用DataRow做為引數值,返回XmlReader型別的結果集.

        /// </summary>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataRow">使用DataRow作為引數值</param>

        /// <returns>返回XmlReader結果集物件.</returns>

        public static XmlReader ExecuteXmlReaderTypedParams(SqlConnection connection, String spName, DataRow dataRow)

        {

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

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



            // 如果row有值,儲存過程必須初始化.

            if( dataRow != null && dataRow.ItemArray.Length > 0)

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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

                

                // 分配引數值

                AssignParameterValues(commandParameters, dataRow);

                

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

            }

            else

            {

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

            }

        }



        /// <summary>

        /// 執行指定連線資料庫事務的儲存過程,使用DataRow做為引數值,返回XmlReader型別的結果集.

        /// </summary>

        /// <param name="transaction">一個有效的連線事務 object</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="dataRow">使用DataRow作為引數值</param>

        /// <returns>返回XmlReader結果集物件.</returns>

        public static XmlReader ExecuteXmlReaderTypedParams(SqlTransaction transaction, String spName, DataRow dataRow)

        {

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

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

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



            // 如果row有值,儲存過程必須初始化.

            if( dataRow != null && dataRow.ItemArray.Length > 0)

            {

                // 從快取中載入儲存過程引數,如果快取中不存在則從資料庫中檢索引數資訊並載入到快取中. ()

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

                

                // 分配引數值

                AssignParameterValues(commandParameters, dataRow);

                

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

            }

            else

            {

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

            }

        }

        #endregion



    }



    /// <summary>

    /// SqlHelperParameterCache提供快取儲存過程引數,並能夠在執行時從儲存過程中探索引數.

    /// </summary>

    public sealed class SqlHelperParameterCache

    {

        #region 私有方法,欄位,建構函式

        // 私有建構函式,妨止類被例項化.

        private SqlHelperParameterCache() {}



        // 這個方法要注意

        private static Hashtable paramCache = Hashtable.Synchronized(new Hashtable());



        /// <summary>

        /// 探索執行時的儲存過程,返回SqlParameter引數陣列.

        /// 初始化引數值為 DBNull.Value.

        /// </summary>

        /// <param name="connection">一個有效的資料庫連線</param>

        /// <param name="spName">儲存過程名稱</param>

        /// <param name="includeReturnValueParameter">是否包含返回值引數</param>

        /// <returns>返回SqlParameter引數陣列</returns>

        private static SqlParameter[] DiscoverSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter)

        {

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

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



            SqlCommand cmd = new SqlCommand(spName, connection);

            cmd.CommandType = CommandType.StoredProcedure;



            connection.Open();

            // 檢索cmd指定的儲存過程的引數資訊,並填充到cmd的Parameters引數集中.

            SqlCommandBuilder.DeriveParameters(cmd);

            connection.Close();

            // 如果不包含返回值引數,將引數集中的每一個引數刪除.

            if (!includeReturnValueParameter) 

            {

                cmd.Parameters.RemoveAt(0);

            }

                

            // 建立引數陣列

            SqlParameter[] discoveredParameters = new SqlParameter[cmd.Parameters.Count];

            // 將cmd的Parameters引數集複製到discoveredParameters陣列.

            cmd.Parameters.CopyTo(discoveredParameters, 0);



            // 初始化引數值為 DBNull.Value.

            foreach (SqlParameter discoveredParameter in discoveredParameters)

            {

                discoveredParameter.Value = DBNull.Value;

            }

            return discoveredParameters;

        }



        /// <summary>

        /// SqlParameter引數陣列的深層拷貝.

        /// </summary>

        /// <param name="originalParameters">原始引數陣列</param>

        /// <returns>返回一個同樣的引數陣列</returns>

        private static SqlParameter[] CloneParameters(SqlParameter[] originalParameters)

        {

            SqlParameter[] clonedParameters = new SqlParameter[originalParameters.Length];



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

            {

                clonedParameters[i] = (SqlParameter)((ICloneable)originalParameters[i]).Clone();

            }



            return clonedParameters;

        }



        #endregion 私有方法,欄位,建構函式結束



        #region 快取方法



        /// <summary>

        /// 追加引數陣列到快取.

        /// </summary>

        /// <param name="connectionString">一個有效的資料庫連線字串</param>

        /// <param name="commandText">儲存過程名或SQL語句</param>

        /// <param name="commandParameters">要快取的引數陣列</param>

        public static void CacheParameterSet(string connectionString, string commandText, params SqlParameter[] commandParameters)

        {

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

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



            string hashKey = connectionString + ":" + commandText;



            paramCache[hashKey] = commandParameters;

        }



        /// <summary>

        /// 從快取中獲取引數陣列.

        /// </summary>

        /// <param name="connectionString">一個有效的資料庫連線字元</param>

        /// <param name="commandText">儲存過程名或SQL語句</param>

        /// <returns>引數陣列</returns>

        public static SqlParameter[] GetCachedParameterSet(string connectionString, string commandText)

        {

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

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



            string hashKey = connectionString + ":" + commandText;



            SqlParameter[] cachedParameters = paramCache[hashKey] as SqlParameter[];

            if (cachedParameters == null)

            {            

                return null;

            }

            else

            {

                return CloneParameters(cachedParameters);

            }

        }



        #endregion 快取方法結束



        #region 檢索指定的儲存過程的引數集



        /// <summary>

        /// 返回指定的儲存過程的引數集

        /// </summary>

        /// <remarks>

        /// 這個方法將查詢資料庫,並將資訊儲存到快取.

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字元</param>

        /// <param name="spName">儲存過程名</param>

        /// <returns>返回SqlParameter引數陣列</returns>

        public static SqlParameter[] GetSpParameterSet(string connectionString, string spName)

        {

            return GetSpParameterSet(connectionString, spName, false);

        }



        /// <summary>

        /// 返回指定的儲存過程的引數集

        /// </summary>

        /// <remarks>

        /// 這個方法將查詢資料庫,並將資訊儲存到快取.

        /// </remarks>

        /// <param name="connectionString">一個有效的資料庫連線字元.</param>

        /// <param name="spName">儲存過程名</param>

        /// <param name="includeReturnValueParameter">是否包含返回值引數</param>

        /// <returns>返回SqlParameter引數陣列</returns>

        public static SqlParameter[] GetSpParameterSet(string connectionString, string spName, bool includeReturnValueParameter)

        {

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

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



            using(SqlConnection connection = new SqlConnection(connectionString))

            {

                return GetSpParameterSetInternal(connection, spName, includeReturnValueParameter);

            }

        }



        /// <summary>

        /// [內部]返回指定的儲存過程的引數集(使用連線物件).

        /// </summary>

        /// <remarks>

        /// 這個方法將查詢資料庫,並將資訊儲存到快取.

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線字元</param>

        /// <param name="spName">儲存過程名</param>

        /// <returns>返回SqlParameter引數陣列</returns>

        internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName)

        {

            return GetSpParameterSet(connection, spName, false);

        }



        /// <summary>

        /// [內部]返回指定的儲存過程的引數集(使用連線物件)

        /// </summary>

        /// <remarks>

        /// 這個方法將查詢資料庫,並將資訊儲存到快取.

        /// </remarks>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="spName">儲存過程名</param>

        /// <param name="includeReturnValueParameter">

        /// 是否包含返回值引數

        /// </param>

        /// <returns>返回SqlParameter引數陣列</returns>

        internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter)

        {

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

            using (SqlConnection clonedConnection = (SqlConnection)((ICloneable)connection).Clone())

            {

                return GetSpParameterSetInternal(clonedConnection, spName, includeReturnValueParameter);

            }

        }



        /// <summary>

        /// [私有]返回指定的儲存過程的引數集(使用連線物件)

        /// </summary>

        /// <param name="connection">一個有效的資料庫連線物件</param>

        /// <param name="spName">儲存過程名</param>

        /// <param name="includeReturnValueParameter">是否包含返回值引數</param>

        /// <returns>返回SqlParameter引數陣列</returns>

        private static SqlParameter[] GetSpParameterSetInternal(SqlConnection connection, string spName, bool includeReturnValueParameter)

        {

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

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



            string hashKey = connection.ConnectionString + ":" + spName + (includeReturnValueParameter ? ":include ReturnValue Parameter":"");



            SqlParameter[] cachedParameters;

            

            cachedParameters = paramCache[hashKey] as SqlParameter[];

            if (cachedParameters == null)

            {    

                SqlParameter[] spParameters = DiscoverSpParameterSet(connection, spName, includeReturnValueParameter);

                paramCache[hashKey] = spParameters;

                cachedParameters = spParameters;

            }

            

            return CloneParameters(cachedParameters);

        }

        

        #endregion 引數集檢索結束



    }

}


相關文章