Browse Source

C# 数据库封装库

Jeff 6 years ago
parent
commit
9d6b385367

+ 31 - 0
SQLHelper/SQLHelper.sln

@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27130.2003
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLHelper", "SQLHelper\SQLHelper.csproj", "{7DA2F5C1-7278-4EA8-9CD8-2871CE367B8C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestCase", "TestCase\TestCase.csproj", "{BA13BB9A-2450-481F-A56C-F132782FA4A2}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{7DA2F5C1-7278-4EA8-9CD8-2871CE367B8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7DA2F5C1-7278-4EA8-9CD8-2871CE367B8C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7DA2F5C1-7278-4EA8-9CD8-2871CE367B8C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7DA2F5C1-7278-4EA8-9CD8-2871CE367B8C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{BA13BB9A-2450-481F-A56C-F132782FA4A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BA13BB9A-2450-481F-A56C-F132782FA4A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BA13BB9A-2450-481F-A56C-F132782FA4A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BA13BB9A-2450-481F-A56C-F132782FA4A2}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {26ABC945-D870-4CE6-A51F-C9BD50F63026}
+	EndGlobalSection
+EndGlobal

+ 525 - 0
SQLHelper/SQLHelper/ConnectionParameters.cs

@@ -0,0 +1,525 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace SQLHelper
+{
+    /// <summary>
+    /// 连接参数
+    /// </summary>
+    [Serializable]
+    public sealed class ConnectionParameters
+    {
+        #region 连接串
+        // 无端口号;
+        private const string _msdbconnect = "Data Source={0};Initial Catalog={1};User ID={2};Password={3}";
+        private const string _msdbconnect_master = "Data Source={0};Initial Catalog=master;User ID={1};Password={2}";
+        // 有端口号;
+        private const string _msdbconnect_port = "Data Source={0},{1};Initial Catalog={2};User ID={3};Password={4}";
+        private const string _msdbconnect_master_port = "Data Source={0},{1};Initial Catalog=master;User ID={2};Password={3}";
+        // windows信任连接;
+        private const string _msdbconnect_trusted_master = "server={0};database=master;Trusted_Connection=SSPI";
+        #endregion
+
+        #region 私有变量;
+        /// <summary>
+        /// 数据库连接串;
+        /// </summary>
+        private string connectionString = "";
+        private string masterConnectionString = "";
+        private string trustedConnectionString = "";
+
+        private string databaseServer = "127.0.0.1";
+        private string databaseAccount = "sa";
+        private string databasePassword = "";
+        private string databaseName = "";
+        private uint databasePort = 0;
+        private uint maxPoolSize = 100;
+        private uint minPoolSize = 5;
+        private uint connectTimeout = 3000;
+        #endregion
+
+        #region 公共属性;
+        /// <summary>
+        /// 数据库服务器;
+        /// </summary>
+        public string DatabaseServer
+        {
+            get { return databaseServer; }
+            set
+            {
+                databaseServer = value;
+                if (IsSetParameters) InitConnectParameters();
+            }
+        }
+        /// <summary>
+        /// 数据库账号;
+        /// </summary>
+        public string DatabaseAccount
+        {
+            get { return databaseAccount; }
+            set
+            {
+                databaseAccount = value;
+                if (IsSetParameters) InitConnectParameters();
+            }
+        }
+        /// <summary>
+        /// 数据库密码;
+        /// </summary>
+        public string DatabasePassword
+        {
+            get { return databasePassword; }
+            set
+            {
+                databasePassword = value;
+                if (IsSetParameters) InitConnectParameters();
+            }
+        }
+        /// <summary>
+        /// 数据库名称;
+        /// </summary>
+        public string DatabaseName
+        {
+            get { return databaseName; }
+            set
+            {
+                databaseName = value;
+                if (IsSetParameters) InitConnectParameters();
+            }
+        }
+        /// <summary>
+        /// 数据库端口号;
+        /// </summary>
+        public uint DatabasePort
+        {
+            get { return databasePort; }
+            set
+            {
+                databasePort = value;
+                if (IsSetParameters) InitConnectParameters();
+            }
+        }
+
+        /// <summary>
+        /// 池最大值;
+        /// </summary>
+        public uint MaxPoolSize { get; set; } = 100;
+
+        /// <summary>
+        /// 池最小值;
+        /// </summary>
+        public uint MinPoolSize { get; set; } = 5;
+
+        /// <summary>
+        /// 连接超时值;
+        /// </summary>
+        public uint ConnectTimeout { get; set; } = 3000;
+
+        [JsonIgnore]
+        /// <summary>
+        /// 是否设置了数据库连接参数;
+        /// </summary>
+        public bool IsSetParameters { get; private set; } = false;
+
+        [JsonIgnore]
+        /// <summary>
+        /// 数据库连接串;
+        /// </summary>
+        public string ConnectionString
+        {
+            get
+            {
+                if (IsSetParameters)
+                    return connectionString;
+                else
+                    return "";
+            }
+        }
+
+        [JsonIgnore]
+        public string MasterConnectionString
+        {
+            get
+            {
+                if (IsSetParameters)
+                    return masterConnectionString;
+                else
+                    return "";
+            }
+        }
+
+        [JsonIgnore]
+        public string TrustedConnectionString
+        {
+            get
+            {
+                if (IsSetParameters)
+                    return trustedConnectionString;
+                else
+                    return "";
+            }
+        }
+        #endregion
+
+        public ConnectionParameters() { }
+
+        public ConnectionParameters(string databaseServer, string databaseName, string databaseAccount, string databasePassword, uint databasePortNumber)
+        {
+            try
+            {
+                // 标记连接参数已设置;
+                IsSetParameters = true;
+
+                // 生成默认的连接串;
+                this.connectionString = DatabasePort== 0
+                    ? string.Format(_msdbconnect, DatabaseServer, DatabaseName, DatabaseAccount, DatabasePassword)
+                    : string.Format(_msdbconnect_port, DatabaseServer, DatabasePort, DatabaseName, DatabaseAccount, DatabasePassword);
+
+                this.masterConnectionString = DatabasePort == 0
+                    ? string.Format(_msdbconnect_master, DatabaseServer, DatabaseAccount, DatabasePassword)
+                    : string.Format(_msdbconnect_master_port, DatabaseServer, DatabasePort, DatabaseAccount, DatabasePassword);
+
+                this.trustedConnectionString = string.Format(_msdbconnect_trusted_master, DatabaseServer);
+            }
+            catch
+            {
+                throw;
+            }
+        }
+
+        public void InitConnectParameters()
+        {
+            try
+            {
+                // 标记连接参数已设置;
+                IsSetParameters = true;
+
+                // 生成默认的连接串;
+                this.connectionString = DatabasePort == 0
+                    ? string.Format(_msdbconnect, DatabaseServer, DatabaseName, DatabaseAccount, DatabasePassword)
+                    : string.Format(_msdbconnect_port, DatabaseServer, DatabasePort, DatabaseName, DatabaseAccount, DatabasePassword);
+
+                this.masterConnectionString = DatabasePort == 0
+                    ? string.Format(_msdbconnect_master, DatabaseServer, DatabaseAccount, DatabasePassword)
+                    : string.Format(_msdbconnect_master_port, DatabaseServer, DatabasePort, DatabaseAccount, DatabasePassword);
+
+                this.trustedConnectionString = string.Format(_msdbconnect_trusted_master, DatabaseServer);
+            }
+            catch
+            {
+                throw;
+            }
+        }
+
+        public void InitConnectParameters(
+           string databaseServer,
+           string databaseName,
+           string databaseAccount,
+           string databasePassword,
+           uint databasePortNumber)
+        {
+            DatabaseServer = databaseServer;
+            DatabaseName = databaseName;
+            DatabaseAccount = databaseAccount;
+            DatabasePassword = databasePassword;
+            DatabasePort = databasePortNumber;
+
+            // 标记连接参数已设置;
+            IsSetParameters = true;
+
+            try
+            {
+                // 生成默认的连接串;
+                this.connectionString = DatabasePort == 0
+                    ? string.Format(_msdbconnect, DatabaseServer, DatabaseName, DatabaseAccount, DatabasePassword)
+                    : string.Format(_msdbconnect_port, DatabaseServer, DatabasePort, DatabaseName, DatabaseAccount, DatabasePassword);
+
+                this.masterConnectionString = DatabasePort == 0
+                    ? string.Format(_msdbconnect_master, DatabaseServer, DatabaseAccount, DatabasePassword)
+                    : string.Format(_msdbconnect_master_port, DatabaseServer, DatabasePort, DatabaseAccount, DatabasePassword);
+
+                this.trustedConnectionString = string.Format(_msdbconnect_trusted_master, DatabaseServer);
+            }
+            catch
+            {
+                throw;
+            }
+        }
+
+        [Obsolete("this function unfinished")]
+        /// <summary>
+        /// 设置连接参数;(未完成)
+        /// </summary>
+        /// <param name="serverIp"></param>
+        /// <param name="database"></param>
+        /// <param name="account"></param>
+        /// <param name="password"></param>
+        /// <param name="port"></param>
+        public void InitConnectParameters(
+            string databaseServer,
+            string databaseName,
+            string databaseAccount,
+            string databasePassword,
+            uint databasePortNumber,
+            uint maxPoolSize = 100,
+            uint minPoolSize = 5,
+            uint connectTimeout = 3000)
+        {
+            DatabaseServer = databaseServer;
+            DatabaseName = databaseName;
+            DatabaseAccount = databaseAccount;
+            DatabasePassword = databasePassword;
+            DatabasePort = databasePortNumber;
+            MaxPoolSize = maxPoolSize;
+            MinPoolSize = minPoolSize;
+            ConnectTimeout = connectTimeout;
+
+            // 标记连接参数已设置;
+            IsSetParameters = true;
+
+            try
+            {
+                // 生成默认的连接串;
+                this.connectionString = DatabasePort == 0
+                    ? string.Format(_msdbconnect, DatabaseServer, DatabaseName, DatabaseAccount, DatabasePassword)
+                    : string.Format(_msdbconnect_port, DatabaseServer, DatabasePort, DatabaseName, DatabaseAccount, DatabasePassword);
+
+                this.masterConnectionString = DatabasePort == 0
+                    ? string.Format(_msdbconnect_master, DatabaseServer, DatabaseAccount, DatabasePassword)
+                    : string.Format(_msdbconnect_master_port, DatabaseServer, DatabasePort, DatabaseAccount, DatabasePassword);
+
+                this.trustedConnectionString = string.Format(_msdbconnect_trusted_master, DatabaseServer);
+            }
+            catch
+            {
+                throw;
+            }
+        }
+
+        #region 特殊的SQL执行函数
+        public bool CreateDatabaseUser(string userName, string password)
+        {
+            try
+            {
+                StringBuilder sqlScript = new StringBuilder();
+                sqlScript.Append("IF  EXISTS (SELECT * FROM sys.server_principals WHERE name = N'" + userName + "')\r\n");
+                sqlScript.Append("DROP LOGIN [" + userName + "]\r\n");
+                sqlScript.Append("CREATE LOGIN [" + userName + "] WITH PASSWORD=N'" + password + "', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=ON\r\n");
+                sqlScript.Append("EXEC master..sp_addsrvrolemember @loginame = N'" + userName + "', @rolename = N'bulkadmin'\r\n");
+                sqlScript.Append("EXEC master..sp_addsrvrolemember @loginame = N'" + userName + "', @rolename = N'dbcreator'\r\n");
+                sqlScript.Append("EXEC master..sp_addsrvrolemember @loginame = N'" + userName + "', @rolename = N'diskadmin'\r\n");
+                sqlScript.Append("EXEC master..sp_addsrvrolemember @loginame = N'" + userName + "', @rolename = N'processadmin'\r\n");
+                sqlScript.Append("EXEC master..sp_addsrvrolemember @loginame = N'" + userName + "', @rolename = N'securityadmin'\r\n");
+                sqlScript.Append("EXEC master..sp_addsrvrolemember @loginame = N'" + userName + "', @rolename = N'serveradmin'\r\n");
+                sqlScript.Append("EXEC master..sp_addsrvrolemember @loginame = N'" + userName + "', @rolename = N'setupadmin'\r\n");
+                sqlScript.Append("EXEC master..sp_addsrvrolemember @loginame = N'" + userName + "', @rolename = N'sysadmin'\r\n");
+                SqlHelper.ExecuteNonQuery(this.MasterConnectionString, CommandType.Text, sqlScript.ToString());
+            }
+            catch (System.Data.SqlClient.SqlException ex)
+            {
+                return false;
+            }
+
+            return true;
+        }
+
+        public bool DeleteDatabaseUser(string userName)
+        {
+            try
+            {
+                System.Text.StringBuilder sqlScript = new System.Text.StringBuilder();
+                sqlScript.Append("IF  EXISTS (SELECT * FROM sys.server_principals WHERE name = N'" + userName + "')\r\n");
+                sqlScript.Append("ALTER LOGIN [" + userName + "] DISABLE\r\n");
+                sqlScript.Append("IF  EXISTS (SELECT * FROM sys.server_principals WHERE name = N'" + userName + "')\r\n");
+                sqlScript.Append("DROP LOGIN [" + userName + "]\r\n");
+                SqlHelper.ExecuteNonQuery(this.MasterConnectionString, CommandType.Text, sqlScript.ToString());
+            }
+            catch (System.Data.SqlClient.SqlException e)
+            {
+                return false;
+            }
+
+            return true;
+        }
+
+        public bool ForcedDisconnect(string databaseName)
+        {
+            System.Text.StringBuilder RestoreSql = new System.Text.StringBuilder();
+            RestoreSql.Append("/* 结束所有对当前数据库的连接 */\r\n");
+            RestoreSql.Append("if exists(select 1 from sys.sysprocesses where dbid=db_id(@databaseName)) begin\r\n");
+            RestoreSql.Append("declare #cs_spid cursor -- 声明游标\r\n");
+            RestoreSql.Append("for\r\n");
+            RestoreSql.Append("select #cs_spid=convert(varchar,spid) from sys.sysprocesses where dbid=db_id(@databaseName)\r\n");
+            RestoreSql.Append("open #cs_spid\r\n");
+            RestoreSql.Append("declare @spid varchar(20)\r\n");
+            RestoreSql.Append("fetch next from #cs_spid into @spid -- 赋值并前进到下一条\r\n");
+            RestoreSql.Append("while(@@fetch_status=0) begin -- 在fetch失败前执行\r\n");
+            RestoreSql.Append("exec ('kill '+@spid) -- 结束对操作库的连接(exec执行SQL语句1)\r\n");
+            RestoreSql.Append("fetch next from #cs_spid into @spid\r\n");
+            RestoreSql.Append("end\r\n");
+            RestoreSql.Append("close #cs_spid\r\n");
+            RestoreSql.Append("deallocate #cs_spid -- 释放游标\r\n");
+            RestoreSql.Append("end");
+            List<System.Data.SqlClient.SqlParameter> parameterlist = new List<System.Data.SqlClient.SqlParameter>();
+
+            parameterlist.Add(new System.Data.SqlClient.SqlParameter("@databaseName", databaseName));
+
+            System.Data.SqlClient.SqlParameter[] parameters = parameterlist.ToArray();
+            System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
+            try
+            {
+                SqlHelper.ExecuteNonQuery(RestoreSql.ToString(), CommandType.Text, this.masterConnectionString, parameters);
+            }
+            catch
+            {
+                return false;
+            }
+
+            return true;
+        }
+
+        public bool IsDatabaseExists(string databaseName, out string dbFilePath)
+        {
+            List<System.Data.SqlClient.SqlParameter> parameterlist = new List<System.Data.SqlClient.SqlParameter>();
+            parameterlist.Add(new System.Data.SqlClient.SqlParameter("@databaseName", databaseName));
+            string sql = "select dbid,name,filename From sysdatabases WHERE NAME=@databaseName";
+            System.Data.SqlClient.SqlParameter[] parameters = parameterlist.ToArray();
+            // System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
+            dbFilePath = "";
+            try
+            {
+                System.Data.DataSet ds = SqlHelper.ExecuteDataset(this.MasterConnectionString, CommandType.Text, sql, parameters);
+                if (ds.Tables[0].Rows.Count > 0)
+                {
+                    dbFilePath = ds.Tables[0].Rows[0]["filename"].ToString();
+                    return true;
+                }
+                else
+                {
+                    return false;
+                }
+            }
+            catch
+            {
+                return false;
+            }
+        }
+
+        public void DatabaseLogRecoveryMode(string databaseName, string mode = "SIMPLE")
+        {
+            string databasePath;
+            if (IsDatabaseExists(databaseName, out databasePath))
+            {
+                List<System.Data.SqlClient.SqlParameter> parameterlist = new List<System.Data.SqlClient.SqlParameter>();
+                parameterlist.Add(new System.Data.SqlClient.SqlParameter("@databaseName", databaseName));
+                parameterlist.Add(new System.Data.SqlClient.SqlParameter("@SIMPLE", databaseName));
+                string sql = "ALTER DATABASE @databaseName SET RECOVERY @SIMPLE ;";
+                System.Data.SqlClient.SqlParameter[] parameters = parameterlist.ToArray();
+                System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
+                try
+                {
+                    SqlHelper.ExecuteNonQuery(this.MasterConnectionString, CommandType.Text, sql.ToString(), parameters);
+                }
+                catch
+                {
+                }
+            }
+        }
+
+        /// <summary>
+        /// 分离数据库;
+        /// 注:如果有外部连接了数据库, 是没办法分离的;
+        /// </summary>
+        /// <param name="databaseName"></param>
+        /// <returns></returns>
+        public bool DetachDatabase(string databaseName)
+        {
+            bool bl = false;
+            string databasePath;
+            if (IsDatabaseExists(databaseName, out databasePath))
+            {
+                List<System.Data.SqlClient.SqlParameter> parameterlist = new List<System.Data.SqlClient.SqlParameter>();
+                parameterlist.Add(new System.Data.SqlClient.SqlParameter("@databaseName", databaseName));
+                string sql = "EXEC master.dbo.sp_detach_db @dbname = @databaseName";
+                System.Data.SqlClient.SqlParameter[] parameters = parameterlist.ToArray();
+                System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
+                try
+                {
+                    ForcedDisconnect(databaseName);
+                    SqlHelper.ExecuteNonQuery(this.MasterConnectionString, CommandType.Text, sql.ToString(), parameters);
+                    if (!IsDatabaseExists(databaseName, out databasePath))
+                    {
+                        bl = true;
+                    }
+                    else
+                    {
+                        bl = false;
+                    }
+                }
+                catch (Exception e)
+                {
+                    bl = false;
+                }
+            }
+            return bl;
+        }
+
+        /// <summary>
+        /// 附加数据库;
+        /// </summary>
+        /// <param name="databaseFilePath"></param>
+        /// <param name="databaseLogsFilePath"></param>
+        /// <param name="databaseName"></param>
+        /// <returns></returns>
+        public bool AttachDatabase(string databaseName, string databaseFilePath, string databaseLogsFilePath)
+        {
+            bool bl = false;
+            string databasePath;
+            if (!IsDatabaseExists(databaseName, out databasePath))
+            {
+                List<System.Data.SqlClient.SqlParameter> parameterlist = new List<System.Data.SqlClient.SqlParameter>();
+                string sql = "CREATE DATABASE [" + databaseName + "] ON ( FILENAME ='" + databaseFilePath + "'  ),( FILENAME ='" + databaseLogsFilePath + "' ) FOR ATTACH";
+                System.Data.SqlClient.SqlParameter[] parameters = parameterlist.ToArray();
+                System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
+                try
+                {
+                    SqlHelper.ExecuteNonQuery(this.MasterConnectionString, CommandType.Text, sql.ToString(), parameters);
+                    if (IsDatabaseExists(databaseName, out databasePath))
+                    {
+                        DatabaseLogRecoveryMode(databaseName);
+                        bl = true;
+                    }
+                    else
+                    {
+                        bl = false;
+                    }
+                }
+                catch (Exception e)
+                {
+                    //e.Message;
+                    bl = false;
+                }
+            }
+            return bl;
+        }
+
+        public bool EnableDatabaseUser(string userName, bool disable)
+        {
+            try
+            {
+                SqlHelper.ExecuteNonQuery(this.TrustedConnectionString, CommandType.Text, string.Format("alter login [{0}] {1}", userName, disable ? "DISABLE" : "ENABLE"));
+            }
+            catch
+            {
+                return false;
+            }
+            return true;
+        }
+        #endregion
+    }
+}

BIN
SQLHelper/SQLHelper/Newtonsoft.Json.dll


+ 36 - 0
SQLHelper/SQLHelper/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("SQLHelper")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SQLHelper")]
+[assembly: AssemblyCopyright("Copyright ©  2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("7da2f5c1-7278-4ea8-9cd8-2871ce367b8c")]
+
+// 程序集的版本信息由下列四个值组成: 
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 2365 - 0
SQLHelper/SQLHelper/SQLHelper.cs

@@ -0,0 +1,2365 @@
+using System;
+using System.Data;
+using System.Xml;
+using System.Data.SqlClient;
+using System.Collections;
+
+namespace SQLHelper
+{
+    /// <summary>
+    /// SqlServer数据访问帮助类
+    /// </summary>
+    public sealed class SqlHelper
+    {
+        #region 私有构造函数和方法
+        private SqlHelper() { }
+        /// <summary>
+        /// 将SqlParameter参数数组(参数值)分配给SqlCommand命令.
+        /// 这个方法将给任何一个参数分配DBNull.Value;
+        /// 该操作将阻止默认值的使用.
+        /// </summary>SqlHelperSqlHelper
+        /// <param>命令名</param>
+        /// <param>SqlParameters数组</param>
+        private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters)
+        {
+            if (command == null)
+                throw new ArgumentNullException("command is null");
+            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>要分配值的SqlParameter参数数组</param>
+        /// <param>将要分配给存储过程参数的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>要分配值的SqlParameter参数数组</param>
+        /// <param>将要分配给存储过程参数的对象数组</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 == null)
+                {
+                    commandParameters[i].Value = DBNull.Value;
+                }
+                else
+                {
+                    commandParameters[i].Value = parameterValues;
+                }
+            }
+        }
+
+        /// <summary>
+        /// 预处理用户提供的命令,数据库连接/事务/命令类型/参数
+        /// </summary>
+        /// <param>要处理的SqlCommand</param>
+        /// <param>数据库连接</param>
+        /// <param>一个有效的事务或者是null值</param>
+        /// <param>命令类型 (存储过程,命令文本, 其它.)</param>
+        /// <param>存储过程名或都T-SQL命令文本</param>
+        /// <param>和命令相关联的SqlParameter参数数组,如果没有参数为'null'</param>
+        /// <param><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 is null");
+            if (commandText == null || commandText.Length == 0)
+                throw new ArgumentNullException("commandText is empty");
+
+            // 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>一个有效的数据库连接字符串</param>
+        /// <param>命令类型 (存储过程,命令文本, 其它.)</param>
+        /// <param>存储过程名称或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>一个有效的数据库连接字符串</param>
+        /// <param>命令类型 (存储过程,命令文本, 其它.)</param>
+        /// <param>存储过程名称或SQL语句</param>
+        /// <param>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>一个有效的数据库连接字符串/param>
+        /// <param>存储过程名称</param>
+        /// <param>分配到存储过程输入参数的对象数组</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>一个有效的数据库连接对象</param>
+        /// <param>命令类型(存储过程,命令文本或其它.)</param>
+        /// <param>存储过程名称或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>一个有效的数据库连接对象</param>
+        /// <param>命令类型(存储过程,命令文本或其它.)</param>
+        /// <param>T存储过程名称或T-SQL语句</param>
+        /// <param>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>一个有效的数据库连接对象</param>
+        /// <param>存储过程名</param>
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的数据库连接对象</param>
+        /// <param>命令类型(存储过程,命令文本或其它.)</param>
+        /// <param>存储过程名称或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>一个有效的数据库连接对象</param>
+        /// <param>命令类型(存储过程,命令文本或其它.)</param>
+        /// <param>存储过程名称或T-SQL语句</param>
+        /// <param>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>一个有效的数据库连接对象</param>
+        /// <param>存储过程名</param>
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的数据库连接字符串</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或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>一个有效的数据库连接字符串</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或T-SQL语句</param>
+        /// <param>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>一个有效的数据库连接字符串</param>
+        /// <param>存储过程名</param>
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的数据库连接对象</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名或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>一个有效的数据库连接对象</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名或T-SQL语句</param>
+        /// <param>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>一个有效的数据库连接对象</param>
+        /// <param>存储过程名</param>
+        /// <param>分配给存储过程输入参数的对象数组</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>事务</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名或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>事务</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名或T-SQL语句</param>
+        /// <param>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>事务</param>
+        /// <param>存储过程名</param>
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的数据库连接对象</param>
+        /// <param>一个有效的事务,或者为 'null'</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名或T-SQL语句</param>
+        /// <param>SqlParameters参数数组,如果没有参数则为'null'</param>
+        /// <param>标识数据库连接对象是由调用者提供还是由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>一个有效的数据库连接字符串</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名或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>一个有效的数据库连接字符串</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名或T-SQL语句</param>
+        /// <param>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>一个有效的数据库连接字符串</param>
+        /// <param>存储过程名</param>
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的数据库连接对象</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名或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>一个有效的数据库连接对象</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>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>一个有效的数据库连接对象</param>
+        /// <param>T存储过程名</param>
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的连接事务</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或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>一个有效的连接事务</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或T-SQL语句</param>
+        /// <param>分配给命令的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>一个有效的连接事务</param>
+        /// <param>存储过程名称</param>
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的数据库连接字符串</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或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>一个有效的数据库连接字符串</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或T-SQL语句</param>
+        /// <param>分配给命令的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>一个有效的数据库连接字符串</param>
+        /// <param>存储过程名称</param>
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的数据库连接对象</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或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>一个有效的数据库连接对象</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或T-SQL语句</param>
+        /// <param>分配给命令的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>一个有效的数据库连接对象</param>
+        /// <param>存储过程名称</param>
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的连接事务</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或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>一个有效的连接事务</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或T-SQL语句</param>
+        /// <param>分配给命令的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>一个有效的连接事务</param>
+        /// <param>存储过程名称</param>
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的数据库连接对象</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或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>一个有效的数据库连接对象</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或T-SQL语句 using "FOR XML AUTO"</param>
+        /// <param>分配给命令的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>一个有效的数据库连接对象</param>
+        /// <param>存储过程名称 using "FOR XML AUTO"</param>
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的连接事务</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或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>一个有效的连接事务</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或T-SQL语句 using "FOR XML AUTO"</param>
+        /// <param>分配给命令的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>一个有效的连接事务</param>
+        /// <param>存储过程名称</param>
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的数据库连接字符串</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或T-SQL语句</param>
+        /// <param>要填充结果集的DataSet实例</param>
+        /// <param>表映射的数据表数组
+        /// 用户定义的表名 (可有是实际的表名.)</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>一个有效的数据库连接字符串</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或T-SQL语句</param>
+        /// <param>分配给命令的SqlParamter参数数组</param>
+        /// <param>要填充结果集的DataSet实例</param>
+        /// <param>表映射的数据表数组
+        /// 用户定义的表名 (可有是实际的表名.)
+        /// </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>一个有效的数据库连接字符串</param>
+        /// <param>存储过程名称</param>
+        /// <param>要填充结果集的DataSet实例</param>
+        /// <param>表映射的数据表数组
+        /// 用户定义的表名 (可有是实际的表名.)
+        /// </param>    
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的数据库连接对象</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或T-SQL语句</param>
+        /// <param>要填充结果集的DataSet实例</param>
+        /// <param>表映射的数据表数组
+        /// 用户定义的表名 (可有是实际的表名.)
+        /// </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>一个有效的数据库连接对象</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或T-SQL语句</param>
+        /// <param>要填充结果集的DataSet实例</param>
+        /// <param>表映射的数据表数组
+        /// 用户定义的表名 (可有是实际的表名.)
+        /// </param>
+        /// <param>分配给命令的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>一个有效的数据库连接对象</param>
+        /// <param>存储过程名称</param>
+        /// <param>要填充结果集的DataSet实例</param>
+        /// <param>表映射的数据表数组
+        /// 用户定义的表名 (可有是实际的表名.)
+        /// </param>
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的连接事务</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或T-SQL语句</param>
+        /// <param>要填充结果集的DataSet实例</param>
+        /// <param>表映射的数据表数组
+        /// 用户定义的表名 (可有是实际的表名.)
+        /// </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>一个有效的连接事务</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或T-SQL语句</param>
+        /// <param>要填充结果集的DataSet实例</param>
+        /// <param>表映射的数据表数组
+        /// 用户定义的表名 (可有是实际的表名.)
+        /// </param>
+        /// <param>分配给命令的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>一个有效的连接事务</param>
+        /// <param>存储过程名称</param>
+        /// <param>要填充结果集的DataSet实例</param>
+        /// <param>表映射的数据表数组
+        /// 用户定义的表名 (可有是实际的表名.)
+        /// </param>
+        /// <param>分配给存储过程输入参数的对象数组</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>一个有效的数据库连接对象</param>
+        /// <param>一个有效的连接事务</param>
+        /// <param>命令类型 (存储过程,命令文本或其它)</param>
+        /// <param>存储过程名称或T-SQL语句</param>
+        /// <param>要填充结果集的DataSet实例</param>
+        /// <param>表映射的数据表数组
+        /// 用户定义的表名 (可有是实际的表名.)
+        /// </param>
+        /// <param>分配给命令的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>[追加记录]一个有效的T-SQL语句或存储过程</param>
+        /// <param>[删除记录]一个有效的T-SQL语句或存储过程</param>
+        /// <param>[更新记录]一个有效的T-SQL语句或存储过程</param>
+        /// <param>要更新到数据库的DataSet</param>
+        /// <param>要更新到数据库的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>一个有效的数据库连接对象</param>
+        /// <param>存储过程名称</param>
+        /// <param>源表的列名称数组</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>一个有效的数据库连接字符串</param>
+        /// <param>存储过程名称</param>
+        /// <param>使用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>一个有效的数据库连接对象</param>
+        /// <param>存储过程名称</param>
+        /// <param>使用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>一个有效的连接事务 object</param>
+        /// <param>存储过程名称</param>
+        /// <param>使用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>一个有效的数据库连接字符串</param>
+        /// <param>存储过程名称</param>
+        /// <param>使用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>一个有效的数据库连接对象</param>
+        /// <param>存储过程名称</param>
+        /// <param>使用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>一个有效的连接事务 object</param>
+        /// <param>存储过程名称</param>
+        /// <param>使用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>一个有效的数据库连接字符串</param>
+        /// <param>存储过程名称</param>
+        /// <param>使用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>一个有效的数据库连接对象</param>
+        /// <param>存储过程名称</param>
+        /// <param>使用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>一个有效的连接事务 object</param>
+        /// <param>存储过程名称</param>
+        /// <param>使用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>一个有效的数据库连接字符串</param>
+        /// <param>存储过程名称</param>
+        /// <param>使用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>一个有效的数据库连接对象</param>
+        /// <param>存储过程名称</param>
+        /// <param>使用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>一个有效的连接事务 object</param>
+        /// <param>存储过程名称</param>
+        /// <param>使用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>一个有效的数据库连接对象</param>
+        /// <param>存储过程名称</param>
+        /// <param>使用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>一个有效的连接事务 object</param>
+        /// <param>存储过程名称</param>
+        /// <param>使用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>一个有效的数据库连接</param>
+        /// <param>存储过程名称</param>
+        /// <param>是否包含返回值参数</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>原始参数数组</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>一个有效的数据库连接字符串</param>
+        /// <param>存储过程名或SQL语句</param>
+        /// <param>要缓存的参数数组</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>一个有效的数据库连接字符</param>
+        /// <param>存储过程名或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>一个有效的数据库连接字符</param>
+        /// <param>存储过程名</param>
+        /// <returns>返回SqlParameter参数数组</returns>
+        public static SqlParameter[] GetSpParameterSet(string connectionString, string spName)
+        {
+            return GetSpParameterSet(connectionString, spName, false);
+        }
+
+        /// <summary>
+        /// 返回指定的存储过程的参数集
+        /// </summary>
+        /// <remarks>
+        /// 这个方法将查询数据库,并将信息存储到缓存.
+        /// </remarks>
+        /// <param>一个有效的数据库连接字符.</param>
+        /// <param>存储过程名</param>
+        /// <param>是否包含返回值参数</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>一个有效的数据库连接字符</param>
+        /// <param>存储过程名</param>
+        /// <returns>返回SqlParameter参数数组</returns>
+        internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName)
+        {
+            return GetSpParameterSet(connection, spName, false);
+        }
+
+        /// <summary>
+        /// [内部]返回指定的存储过程的参数集(使用连接对象)
+        /// </summary>
+        /// <remarks>
+        /// 这个方法将查询数据库,并将信息存储到缓存.
+        /// </remarks>
+        /// <param>一个有效的数据库连接对象</param>
+        /// <param>存储过程名</param>
+        /// <param>
+        /// 是否包含返回值参数
+        /// </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>一个有效的数据库连接对象</param>
+        /// <param>存储过程名</param>
+        /// <param>是否包含返回值参数</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 参数集检索结束
+    }
+}

+ 52 - 0
SQLHelper/SQLHelper/SQLHelper.csproj

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{7DA2F5C1-7278-4EA8-9CD8-2871CE367B8C}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>SQLHelper</RootNamespace>
+    <AssemblyName>SQLHelper</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>.\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ConnectionParameters.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SQLHelper.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 6 - 0
SQLHelper/TestCase/App.config

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
+    </startup>
+</configuration>

+ 589 - 0
SQLHelper/TestCase/Program.cs

@@ -0,0 +1,589 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+/// <summary>
+/// 测试用例
+/// </summary>
+namespace TestCase
+{
+    class Program
+    {
+        static System.Data.DataSet dataSet = null;
+        public static SQLHelper.ConnectionParameters Parameters { get; set; } = new SQLHelper.ConnectionParameters();
+        static void Main( string[] args )
+        {
+            // 打开一个数据库;
+            OpenDatabase();
+            // 初始化数据库连接串;
+            InitConnection();
+            // 分离数据库(不需要admin权限);
+            //Parameters.DetachDatabase("db");
+            // 附加数据库(程序需要使用admin权限运行, 否则附加失败);
+            //Parameters.AttachDatabase("db", @"E:\lyfzClassicSoft\服务端\数据\db.mdf", @"E:\lyfzClassicSoft\服务端\数据\db_log.LDF");
+            /*
+            // 不参数化的sql语句;
+            QueryWithCommandText();
+            // 参数化的sql语句;
+            QueryWithParameters();
+
+            // 表是否存在;
+            if ( IsTableExists("dindan") )
+                Console.WriteLine("表存在");
+            else
+                Console.WriteLine("表不存在");
+
+            // 表字段是否存在;
+            if ( IsColumnExists("dindan", "id1") )
+                Console.WriteLine("表字段存在");
+            else
+                Console.WriteLine("表字段不存在");
+
+            // 视图是否存在;
+            if ( IsViewExists("dindanclient1") )
+                Console.WriteLine("视图存在");
+            else
+                Console.WriteLine("视图不存在");
+                */
+            //Test("Development", "lowdb");
+            //Test("Development", "lowdb2");
+
+            //Test2("Development", "lowdb");
+            //Test2("Development", "lowdb2");
+
+            //Test3("Development", "lowdb", "select * from Vw_OrderReport where Ord_Type in ('0','1','2') and (取件状态 is null or 取件状态 in (0,1))");
+            //Test3("Development", "lowdb", "select * from Vw_OrderProcessCustomer");
+
+            //Test3("Development", "lowdb2", "select * from Vw_OrderReport where Ord_Type in ('0','1','2') and (取件状态 is null or 取件状态 in (0,1))");
+            //Test3("Development", "lowdb2", "select * from Vw_OrderProcessCustomer");
+
+            //Test3("192.168.1.19,1433", "LYFZERPDB", "select * from Vw_OrderReport where Ord_Type in ('0','1','2') and (取件状态 is null or 取件状态 in (0,1))");
+            //Test3("192.168.1.19,1433", "LYFZERPDB", "select * from Vw_OrderProcessCustomer");
+
+
+            Test5("Development", "Platinum");
+
+            // 结束程序;
+            Console.ReadKey();
+        }
+
+        /// <summary>
+        /// 打开一个数据库连接;
+        /// </summary>
+        public static void OpenDatabase()
+        {
+            // 创建连接参数对象, 并初始所有参数;
+            SQLHelper.ConnectionParameters parameters = new SQLHelper.ConnectionParameters();
+
+            // 数据库服务地址;
+            parameters.DatabaseServer = "127.0.0.1";
+            // 数据库服务地址端口号;
+            parameters.DatabasePort = 0;
+            // 数据库名称;
+            parameters.DatabaseName = "db";
+            // 数据库账号;
+            parameters.DatabaseAccount = "sa";
+            // 数据库密码;
+            parameters.DatabasePassword = "ly1234";
+
+            // 初始化连接串;
+            parameters.InitConnectParameters();
+
+            // 打印出连接串;
+            System.Diagnostics.Debug.Write(parameters.ConnectionString + "\n", "正常连接串");
+            System.Diagnostics.Debug.Write(parameters.MasterConnectionString + "\n", "Master连接串");
+            System.Diagnostics.Debug.Write(parameters.TrustedConnectionString + "\n", "本地信任连接串");
+
+            // 创建一个连接对象;
+            try
+            {
+                System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(parameters.ConnectionString);
+                connection.Open();
+                Console.WriteLine("成功打开连接\n");
+            }
+            catch ( Exception e )
+            {
+                Console.WriteLine(e.Message);
+            }
+        }
+
+        /// <summary>
+        /// 初始化数据库连接串;
+        /// </summary>
+        public static void InitConnection()
+        {
+            // 数据库服务地址;
+            Parameters.DatabaseServer = "127.0.0.1";
+            // 数据库服务地址端口号;
+            Parameters.DatabasePort = 0;
+            // 数据库名称;
+            Parameters.DatabaseName = "db";
+            // 数据库账号;
+            Parameters.DatabaseAccount = "sa";
+            // 数据库密码;
+            Parameters.DatabasePassword = "ly1234";
+
+            // 初始化连接串;
+            Parameters.InitConnectParameters();
+
+            // 该函数未完成,不建议使用(当前使用结果与上一句一致);
+            Parameters.InitConnectParameters(
+                Parameters.DatabaseServer,
+                Parameters.DatabaseName,
+                Parameters.DatabaseAccount,
+                Parameters.DatabasePassword,
+                Parameters.DatabasePort, 100, 5, 300);
+        }
+
+        public static void QueryWithCommandText()
+        {
+            try
+            {
+                // 查询数据集: 不使用参数化, 直接语句查询;
+                System.Data.DataTable dt = SQLHelper.SqlHelper.ExecuteDataset(Parameters.ConnectionString, System.Data.CommandType.Text, "select * from dindan where time1 > '2016-01-01'").Tables[0];
+                if ( dt != null && dt.Rows.Count != 0 )
+                {
+                    for ( int i = 0; i < dt.Rows.Count; i++ )
+                    {
+                        Console.WriteLine("{0}, {1}, {2}\n", dt.Rows[i]["id"], dt.Rows[i]["name1"], dt.Rows[i]["name2"]);
+                    }
+                }
+            }
+            catch ( Exception e )
+            {
+                Console.WriteLine(e.Message);
+            }
+        }
+
+        public static void QueryWithParameters()
+        {
+            try
+            {
+                // 查询数据集: 使用参数化;
+                System.Data.SqlClient.SqlParameter[] sqlParameters =
+                {
+                    new System.Data.SqlClient.SqlParameter("@time1", "2016-01-01"),
+                    new System.Data.SqlClient.SqlParameter("@taoxijiage", "500")
+                };
+
+                System.Data.DataTable dt = SQLHelper.SqlHelper.ExecuteDataset(
+                    Parameters.ConnectionString,
+                    System.Data.CommandType.Text,
+                    "select * from dindan where time1 > @time1 and taoxijiage > @taoxijiage",
+                    sqlParameters).Tables[0];
+
+                if ( dt != null && dt.Rows.Count != 0 )
+                {
+                    for ( int i = 0; i < dt.Rows.Count; i++ )
+                    {
+                        Console.WriteLine("{0}, {1}, {2}, {3}\n", dt.Rows[i]["id"], dt.Rows[i]["name1"], dt.Rows[i]["name2"], dt.Rows[i]["taoxijiage"]);
+                    }
+                }
+            }
+            catch ( Exception e )
+            {
+                Console.WriteLine(e.Message);
+            }
+        }
+
+        /// <summary>
+        /// 指定表名是否存在;
+        /// </summary>
+        /// <param name="tableName"></param>
+        /// <returns></returns>
+        public static bool IsTableExists( string tableName )
+        {
+            string strSQL = "select count(*) from sysobjects where id = object_id(N'[" + tableName + "]') and OBJECTPROPERTY(id, N'IsUserTable') = 1";
+            object obj = SQLHelper.SqlHelper.ExecuteScalar(Parameters.ConnectionString, System.Data.CommandType.Text, strSQL);
+
+            if ( (Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)) )
+                return false;
+
+            return (int.Parse(obj.ToString()) > 0) ? true : false;
+        }
+
+        /// <summary>
+        /// 指定表的字段是否存在;
+        /// </summary>
+        /// <param name="tableName"></param>
+        /// <param name="columnName"></param>
+        /// <returns></returns>
+        public static bool IsColumnExists( string tableName, string columnName )
+        {
+            string strSQL = "select count(1) from syscolumns where [id]=object_id('" + tableName + "') and [name]='" + columnName + "'";
+            object obj = SQLHelper.SqlHelper.ExecuteScalar(Parameters.ConnectionString, System.Data.CommandType.Text, strSQL);
+
+            if ( (Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)) )
+                return false;
+
+            return (int.Parse(obj.ToString()) > 0) ? true : false;
+        }
+
+        /// <summary>
+        /// 视图是否存在;
+        /// </summary>
+        /// <param name="viewName"></param>
+        /// <returns></returns>
+        public static bool IsViewExists( string viewName )
+        {
+            string strSQL = "SELECT count([object_id]) as objCount FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[" + viewName + "]')";
+            object obj = SQLHelper.SqlHelper.ExecuteScalar(Parameters.ConnectionString, System.Data.CommandType.Text, strSQL);
+
+            if ( (Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)) )
+                return false;
+
+            return (int.Parse(obj.ToString()) > 0) ? true : false;
+        }
+
+        public static void Test( string server, string dbname )
+        {
+            Stopwatch stopWatch = new Stopwatch();
+            stopWatch.Start();
+
+            try
+            {
+                // 更改参数;
+                Parameters.DatabaseServer = server;
+                Parameters.DatabaseName = dbname;
+
+                string strSql = @"
+                                --订单的取件状态;
+                                with cte_OrderPickup as(
+                                select OPlist_OrderNumber as OrderNumber
+                                ,OPlist_ViceNumber as ViceNumber
+                                ,max(OPlist_PickupTime) as PickupTime
+                                ,(case 
+                                when count(1) = count(case when OPlist_PickupStatus = 0 then '未取' end)	then 0		-- 完全未取;
+                                when count(1) != count(case when OPlist_PickupStatus = 1 then '已取' end)	then 1		-- 取件中;
+                                when count(1) = count(case when OPlist_PickupStatus = 1 then '已取' end)	then 2		-- 全部取完;
+                                end) as PickupStatus
+                                from tb_ErpOrderProductList
+                                where OPlist_Type = '2' 
+                                group by OPlist_ViceNumber,OPlist_OrderNumber
+                                ),
+                                -- 订单接单人;
+                                cte_OrderMan as (
+                                select OrdPe_OrderNumber, User_Name from tb_ErpOrdersPerson Left Join tb_ErpUser ON tb_ErpOrdersPerson.OrdPe_OrdersPerson = tb_ErpUser.User_EmployeeID
+                                ),
+                                cte_OrderPerson as (
+
+                                select 
+                                tb1.OrdPe_OrderNumber as OrderNumber
+                                ,stuff((
+                                select ','+ User_Name
+                                from cte_OrderMan as tb0 where tb0.OrdPe_OrderNumber = tb1.OrdPe_OrderNumber
+                                for xml path('')),1,1,'') as OrderPerson
+                                from cte_OrderMan as tb1
+                                group by tb1.OrdPe_OrderNumber
+                                
+                                --select dbo.AggregateString([User_Name]+'{$$},') as OrderPerson, OrdPe_OrderNumber as OrderNumber from cte_OrderMan group by  OrdPe_OrderNumber
+                                ),
+                                --拍照状态;
+                                cte_PhotographyStatus as(
+                                select max(Ordpg_Number) Ordpg_Number
+                                ,Ordpg_ViceNumber
+                                ,max(Ordpg_Sights) as Ordpg_Sights
+                                ,max(Ordpg_PhotographyTime) as Ordpg_PhotographyTime
+                                ,case when count(case when Ordpg_PhotographyStatus = 1 then '拍照' end) = Count(1) then 1 else 0 end as Ordpg_PhotographyStatus
+                                from tb_ErpOrdersPhotography 
+                                group by Ordpg_ViceNumber
+                                )
+                                select 
+                                ---------------------------------------------------------------
+                                tb_ErpOrder.ID
+                                ,tb_ErpOrder.Ord_DividedShop 分店编号
+                                ,tb_ErpOrder.Ord_Number 订单号
+                                ,tb_ErpOrder.Ord_Class 
+                                ,tb_ErpOrder.Ord_OrderClass 
+                                ,tb_ErpOrder.Ord_SinceOrderNumber 自定义订单号
+                                ,tb_ErpOrder.Ord_Type 订单类型
+                                ,tb_ErpOrder.Ord_PhotographyCategory 套系类型
+                                ,tb_ErpOrder.Ord_CustomerSource 客户来源
+                                ,tb_ErpOrder.Ord_SeriesName 套系名称
+                                ,tb_ErpOrder.Ord_SeriesPrice 套系价格
+                                ---------------------------------------------------------------
+                                ,cte_OrderPickup.OrderNumber 订单号
+                                ,cte_OrderPickup.PickupStatus 订单取件状态
+                                ,cte_OrderPickup.PickupTime 订单最大取件日期
+                                ---------------------------------------------------------------
+                                ,cte_OrderPerson.OrderNumber 订单号
+                                ,cte_OrderPerson.OrderPerson 订单接单人
+                                ---------------------------------------------------------------
+                                ,tempTB_AggregationCustomer.GP_OrderNumber 订单号
+                                ,tempTB_AggregationCustomer.[Cus_CustomerSource] 顾客来源
+                                ,tempTB_AggregationCustomer.Cus_Name 顾客姓名
+                                ,tempTB_AggregationCustomer.Cus_Name_py 顾客姓名接单
+                                ,tempTB_AggregationCustomer.Cus_Sex_cs 顾客性别
+                                ,tempTB_AggregationCustomer.Cus_Telephone 顾客电话
+                                ,tempTB_AggregationCustomer.Cus_OpenID 顾客微信号
+                                ---------------------------------------------------------------
+                                ,tb_ErpOrderDigital.Ordv_Number 订单号
+                                ,tb_ErpOrderDigital.Ordv_ViceNumber 副订单号
+                                ,tb_ErpOrderDigital.Ordv_EarlyRepairStatus 初修状态
+                                ,tb_ErpOrderDigital.Ordv_EarlyRepairTime 初修时间
+                                ,tb_ErpOrderDigital.Ordv_FilmSelectionStatus 选片状态
+                                ,tb_ErpOrderDigital.Ordv_FilmSelectionTime 选片时间
+                                ,tb_ErpOrderDigital.Ordv_DesignerStatus 设计状态
+                                ,tb_ErpOrderDigital.Ordv_DesignerTime 设计时间
+                                ,tb_ErpOrderDigital.Ordv_RefinementStatus 精修状态
+                                ,tb_ErpOrderDigital.Ordv_RefinementTime 精修时间
+                                ,tb_ErpOrderDigital.Ordv_LookDesignStatus 看设计状态
+                                ,tb_ErpOrderDigital.Ordv_LookDesignTime 看设计时间
+                                ---------------------------------------------------------------
+                                ,cte_PhotographyStatus.Ordpg_Sights 景点名
+                                ,cte_PhotographyStatus.Ordpg_PhotographyStatus 拍照状态
+                                ,cte_PhotographyStatus.Ordpg_PhotographyTime 拍照时间
+                                ---------------------------------------------------------------
+                                from tb_ErpOrder
+                                Left Join cte_OrderPerson ON cte_OrderPerson.OrderNumber = tb_ErpOrder.Ord_Number
+                                Left Join tb_ErpOrderDigital ON tb_ErpOrder.Ord_Number = tb_ErpOrderDigital.Ordv_Number
+                                Left Join tempTB_AggregationCustomer ON tempTB_AggregationCustomer.GP_OrderNumber = tb_ErpOrder.Ord_Number
+                                Left Join cte_OrderPickup ON cte_OrderPickup.ViceNumber = tb_ErpOrderDigital.Ordv_ViceNumber
+                                Left Join tb_ErpOrdersPhotography ON tb_ErpOrderDigital.Ordv_ViceNumber = tb_ErpOrdersPhotography.Ordpg_ViceNumber
+                                Left Join cte_PhotographyStatus ON cte_PhotographyStatus.Ordpg_ViceNumber = tb_ErpOrderDigital.Ordv_ViceNumber
+                                ";
+
+                dataSet = SQLHelper.SqlHelper.ExecuteDataset(Parameters.ConnectionString, System.Data.CommandType.Text, strSql);
+            }
+            catch { }
+
+            stopWatch.Stop();
+            long ticksThisTime = stopWatch.ElapsedMilliseconds;
+            Console.WriteLine("{0}用时{1}", dbname, ticksThisTime);
+        }
+
+        public static void Test2( string server, string dbname )
+        {
+            Stopwatch stopWatch = new Stopwatch();
+            stopWatch.Start();
+
+            try
+            {
+                // 更改参数;
+                Parameters.DatabaseServer = server;
+                Parameters.DatabaseName = dbname;
+
+                dataSet = SQLHelper.SqlHelper.ExecuteDataset(Parameters.ConnectionString, System.Data.CommandType.Text, "select * from Vw_OrderProcessCustomer");
+            }
+            catch
+            {
+            }
+
+            stopWatch.Stop();
+            long ticksThisTime = stopWatch.ElapsedMilliseconds;
+            Console.WriteLine("{0}用时{1}", dbname, ticksThisTime);
+        }
+
+        public static void Test3( string server, string dbname, string strSql )
+        {
+            Stopwatch stopWatch = new Stopwatch();
+            stopWatch.Start();
+
+            try
+            {
+                // 更改参数;
+                Parameters.DatabaseServer = server;
+                Parameters.DatabaseName = dbname;
+
+                dataSet = SQLHelper.SqlHelper.ExecuteDataset(Parameters.ConnectionString, System.Data.CommandType.Text, strSql);
+            }
+            catch
+            {
+            }
+
+            stopWatch.Stop();
+            long ticksThisTime = stopWatch.ElapsedMilliseconds;
+            Console.WriteLine("{0}用时{1}", dbname, ticksThisTime);
+        }
+
+        public static void Test4( string server, string dbname )
+        {
+            Stopwatch stopWatch = new Stopwatch();
+            stopWatch.Start();
+
+            System.Data.DataTable dt = null;
+
+            try
+            {
+                // 更改参数;
+                Parameters.DatabaseServer = server;
+                Parameters.DatabaseName = dbname;
+
+                dataSet = SQLHelper.SqlHelper.ExecuteDataset(Parameters.ConnectionString, System.Data.CommandType.Text, "select * from Vw_OrderProcessCustomerEx");
+                if ( dataSet != null && dataSet.Tables.Count != 0 )
+                {
+                    dt = dataSet.Tables[0];
+                    for ( int i = dt.Rows.Count - 1; i > 0; i-- )
+                    {
+                        System.Data.DataRow dr = dt.Rows[i];
+
+                        if ( dr["Ord_DividedShop"].ToString() != "SSN001" )
+                        {
+                            dt.Rows.RemoveAt(i);
+                            continue;
+                        }
+
+                        if ( dr["拍照状态"].ToString() != "OK" )
+                        {
+                            dt.Rows.RemoveAt(i);
+                            continue;
+                        }
+
+                        if ( dr["选片状态"].ToString() != "未选" )
+                        {
+                            dt.Rows.RemoveAt(i);
+                            continue;
+                        }
+
+                        if ( dr["取件状态"].ToString() == "OK" )
+                        {
+                            dt.Rows.RemoveAt(i);
+                            continue;
+                        }
+                    }
+                }
+            }
+            catch
+            {
+            }
+
+            stopWatch.Stop();
+            long ticksThisTime = stopWatch.ElapsedMilliseconds;
+            Console.WriteLine("{0}用时{1}, {2}, {3}", dbname, ticksThisTime, dataSet.Tables[0].Rows.Count, dt.Rows.Count);
+        }
+
+        public static void Test5( string server, string dbname )
+        {
+            string strSql = @"  -- 成本核算
+                                ------------------------------------------------------
+                                --订单接单人员;
+                                with cte_OrderMan as (
+                                select OrdPe_OrderNumber, User_Name from tb_ErpOrdersPerson Left Join tb_ErpUser ON tb_ErpOrdersPerson.OrdPe_OrdersPerson = tb_ErpUser.User_EmployeeID
+                                ),
+                                cte_OrderPerson as (
+                                select 
+                                tb1.OrdPe_OrderNumber as OrderNumber
+                                ,stuff(
+                                (select ','+ User_Name from cte_OrderMan as tb0 
+                                where tb0.OrdPe_OrderNumber = tb1.OrdPe_OrderNumber 
+                                for xml path('')),1,1,''
+                                ) as OrderPerson
+                                from cte_OrderMan as tb1
+                                group by tb1.OrdPe_OrderNumber
+                                ),
+                                ------------------------------------------------------
+                                --订单取件状态;
+                                cte_PickupStatus as (
+                                select 
+                                max(OPlist_OrderNumber) OrderNumber
+                                ,max(OPlist_PickupTime) PickupTime
+                                ,OPlist_ViceNumber
+                                ,case sum(convert(int,OPlist_PickupStatus)) 
+                                when 0 then 0			-- 未取;
+                                when count(1) then 2	-- 已取;
+                                else 1					-- 部分取件;
+                                end as PickupStatus 
+                                from tb_ErpOrderProductList where OPlist_Type = '2' group by OPlist_ViceNumber
+                                ),
+                                ------------------------------------------------------
+                                cte_Scenery as (
+                                select max(Ordpg_Number) OrderNumber, Ordpg_ViceNumber 
+                                ,stuff(
+                                (select ','+ Ordpg_Sights from tb_ErpOrdersPhotography as tb0 
+                                where tb0.Ordpg_ViceNumber = tb1.Ordpg_ViceNumber 
+                                for xml path('')),1,1,''
+                                ) as 景点
+                                from tb_ErpOrdersPhotography tb1 group by Ordpg_ViceNumber
+                                )
+                                ------------------------------------------------------
+                                select 
+                                tb_ErpOrder.Ord_Number
+                                --,tb_ErpOrder.Ord_SinceOrderNumber
+                                --,tb_ErpOrder.Ord_Type
+                                --,tb_ErpOrder.Ord_Class
+                                --,tb_ErpOrder.Ord_OrderClass
+                                ,tb_ErpOrder.Ord_SeriesName 套系名称
+                                ,tb_ErpOrder.Ord_SeriesPrice 套系价格
+                                --,tb_ErpOrder.Ord_Discount
+                                --,tb_ErpOrder.Ord_CreateDateTime
+                                --,tb_ErpOrder.Ord_DividedShop
+                                ------------------------------------------------------
+                                --,tempTB_AggregationCustomer.GP_OrderNumber
+                                ,tempTB_AggregationCustomer.Cus_Name 顾客姓名
+                                --,tempTB_AggregationCustomer.Cus_Name_py
+                                --,tempTB_AggregationCustomer.Cus_Sex_cs
+                                --,tempTB_AggregationCustomer.Cus_Telephone
+                                ------------------------------------------------------
+                                --,cte_OrderPerson.OrderNumber
+                                ,cte_OrderPerson.OrderPerson 接单人
+                                ------------------------------------------------------
+                                ,cte_Scenery.景点
+                                ------------------------------------------------------
+                                --,cte_PickupStatus.OPlist_ViceNumber 子订单
+                                ,cte_PickupStatus.PickupStatus 取件状态
+                                ,cte_PickupStatus.PickupTime 取件时间
+                                ------------------------------------------------------
+
+                                ,isnull(
+                                (Ord_SeriesPrice + case when (select sum(case when Plu_GoodsCosts <> '' then convert(decimal(10,2),dbo.fn_GetSumArray(Plu_GoodsCosts)) else 0 end) from tb_ErpPlusPickItems where Plu_OrdNumber = Ord_Number) is null then 0 
+                                end ),0.00
+                                ) as 套系价格
+
+                                ,(
+                                isnull((select sum(OPlist_CostPrice * OPlist_ProdQuantity) from tb_ErpOrderProductList where OPlist_Type = '1' And OPlist_OrderNumber = Ord_Number),0) + 
+                                isnull((select sum(Ws_ProdCostPrice * Ws_ProdQuantity) from tb_ErpWeddingService where Ws_Number = Ord_Number),0) + 
+                                isnull((select sum(Ordpg_CostPrice) from tb_ErpOrdersPhotography where Ordpg_Number = Ord_Number),0) + 
+                                isnull((select sum(case when Plu_GoodsCosts <> '' then convert(decimal(10,2),dbo.fn_GetSumArray(Plu_GoodsCosts)) else 0 end) from tb_ErpPlusPickItems where Plu_OrdNumber = Ord_Number),0)
+                                ) AS 套系成本 
+
+                                ,(
+                                select sum(OPlist_CostPrice * OPlist_ProdQuantity) from tb_ErpOrderProductList where OPlist_Type = '1' And OPlist_OrderNumber = Ord_Number
+                                ) as 商品成本
+
+                                ,(
+                                select sum(Ws_ProdCostPrice * Ws_ProdQuantity) from tb_ErpWeddingService where Ws_Number = Ord_Number
+                                ) as 服务成本
+
+                                ,(
+                                select sum(Ordpg_CostPrice) from tb_ErpOrdersPhotography where Ordpg_Number = Ord_Number
+                                ) as 景点成本
+
+                                ,(
+                                select sum(case when Plu_GoodsCosts <> '' then convert(decimal(10,2),dbo.fn_GetSumArray(Plu_GoodsCosts)) else 0 end) from tb_ErpPlusPickItems where Plu_OrdNumber = Ord_Number
+                                ) as 加挑总价
+
+                                ------------------------------------------------------
+                                from tb_ErpOrder 
+                                Left Join tempTB_AggregationCustomer ON tb_ErpOrder.Ord_Number = tempTB_AggregationCustomer.GP_OrderNumber
+                                Left Join cte_OrderPerson ON tb_ErpOrder.Ord_Number = cte_OrderPerson.OrderNumber
+                                Left Join cte_PickupStatus ON tb_ErpOrder.Ord_Number = cte_PickupStatus.OrderNumber
+                                Left Join cte_Scenery ON tb_ErpOrder.Ord_Number = cte_Scenery.OrderNumber
+
+                                order by tb_ErpOrder.Ord_Number";
+
+            Stopwatch stopWatch = new Stopwatch();
+            stopWatch.Start();
+
+            System.Data.DataTable dt = null;
+
+            try
+            {
+                // 更改参数;
+                Parameters.DatabaseServer = server;
+                Parameters.DatabaseName = dbname;
+
+                dataSet = SQLHelper.SqlHelper.ExecuteDataset(Parameters.ConnectionString, System.Data.CommandType.Text, strSql);
+            }
+            catch
+            {
+            }
+
+            stopWatch.Stop();
+            long ticksThisTime = stopWatch.ElapsedMilliseconds;
+            Console.WriteLine("{0}用时{1}", dbname, ticksThisTime);
+        }
+    }
+}

+ 36 - 0
SQLHelper/TestCase/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("TestCase")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("TestCase")]
+[assembly: AssemblyCopyright("Copyright ©  2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("ba13bb9a-2450-481f-a56c-f132782fa4a2")]
+
+// 程序集的版本信息由下列四个值组成: 
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
+// 方法是按如下所示使用“*”: :
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 58 - 0
SQLHelper/TestCase/TestCase.csproj

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{BA13BB9A-2450-481F-A56C-F132782FA4A2}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>TestCase</RootNamespace>
+    <AssemblyName>TestCase</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\SQLHelper\SQLHelper.csproj">
+      <Project>{7da2f5c1-7278-4ea8-9cd8-2871ce367b8c}</Project>
+      <Name>SQLHelper</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>