Aircoinst 三层架构ASP.NET开源

<注意! 本源码为我本人所写,可能有点烂。仅供学习使用,请勿进行商业用途~!>

<本源码永久归于MineLSGAircoinst_慈 所拥有>

使用方法:直接拷贝

一、结构&环境介绍

<数据结构> 如下

BLL 业务逻辑层

DAL 数据交换层

FULL 全局变量

Model 实体类

UI 层为 WebApp

数据库为:SQL SERVER 2008 R2

IDE为:Visual Studio 2019 Pro

层的引用如下所示

BLL →DAL

BLL → Model

DAL → Model

FULL  → BLL

FULL → Model

UI → 全部层

这几个层是什么意思想必大家都知道

[FULL]层负责控制全局的用户ID 和用户名

2、ASP.NET 版本为.NET farmworker 4.6版本  服务器为 IIS7.0版本 数据库为 SQL SERVER 2008R2

二、目录介绍

1、BLL 业务逻辑层

(1)inquire.cs类

验证登录是否成功

源码如下:

 1 /*----------------------------------------------------------------
 2 * 项目名称 :BLL
 3 * 项目描述 :
 4 * 类 名 称 :Inquire
 5 * 类 描 述 :
 6 * 所在的域 :AIRCOINST
 7 * 命名空间 :BLL
 8 * 机器名称 :AIRCOINST 
 9 * CLR 版本 :4.0.30319.42000
10 * 作    者 :RenZe
11 * 创建时间 :2019/5/12 11:50:38
12 * 更新时间 :2019/5/12 11:50:38
13 * 版 本 号 :v1.0.0.0
14 *******************************************************************
15 * Copyright @ RenZe 2019. All rights reserved.
16 *******************************************************************
17 //----------------------------------------------------------------*/
18 #endregion
19 using System.Collections.Generic;
20 using System.Linq;
21 using System.Text;
22 using DAL;
23 using Model;
24 using System.Threading.Tasks;
25 using System.Windows.Forms;
26 using System;
27 namespace BLL
28 {
29     public class Inquire
30     {
31     }
32     public class Inquire_Sign
33     {
34         public User_Table user_Login(string NickName, string Password)
35         {
36             InquireData inquireData = new InquireData();
37             User_Table user_Table = inquireData.select_Usert(NickName, Password);
38             if (user_Table != null)
39             {
40                 return user_Table;
41             }
42             else
43             {
44                 throw new Exception("登陆失败");
45             }
46         }
47     }  //用户登陆
48     public class Inquire_Query_User 
49     {
50         public User_Table user_Query(string UserID,string UserName)
51         {
52             InquireData inquireData = new InquireData();
53             User_Table user_Table = inquireData.select_Userts(UserID, UserName);
54             if (user_Table != null)
55             {
56                 return user_Table;
57             }
58             else
59             {
60                 throw new Exception("查询失败");
61             }
62         }
63     }  //查询个人信息
64     public class Inquire_Query_User_Login_record
65     {
66         public User_Table user_Query(string UserID,string Login_record)
67         {
68             InquireData inquireData = new InquireData();
69             User_Table user_Table = inquireData.SelectLogin_record(UserID, Login_record);
70             if (user_Table != null)
71             {
72                 return user_Table;
73             }
74             else
75             {
76                 throw new Exception("查询失败");
77             }
78         }
79     }   //查询登陆次数
80 }

-----------inquire.cs类-----------

(2)LoginManger.cs类 

用于登录验证

源码如下

#region << 版 本 注 释 >>
/*----------------------------------------------------------------
* 项目名称 :BLL
* 项目描述 :
* 类 名 称 :LoginManger
* 类 描 述 :
* 所在的域 :AIRCOINST
* 命名空间 :BLL
* 机器名称 :AIRCOINST 
* CLR 版本 :4.0.30319.42000
* 作    者 :RenZe
* 创建时间 :2019/5/11 23:45:13
* 更新时间 :2019/5/11 23:45:13
* 版 本 号 :v1.0.0.0
*******************************************************************
* Copyright @ RenZe 2019. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DAL;
using Model;

namespace BLL
{
    public class LoginManger
    {
        private DataWrite dataWrite = new DataWrite();
        public bool Add(User_Table user_Table, out string messageStr)
        {
            messageStr = "";
            bool isSuccess = false;
            if (user_Table.UserName.Trim().Length != 0)
            {
                dataWrite.AddUser(user_Table);
                isSuccess = true;
                //if (userDB.Equals(userInfo))
                //{
                //    userDB.AddUser(userInfo);
                //    isSuccess = true;
                //}
                //else
                //{
                //    messageStr = "有相同的值";
                //}
            }
            else
            {
                messageStr = "不能为空";
            }
            return isSuccess;
        }
    }    //用户注册验证
    
    public class Login_record
    {
        private DataWrite dataWrite = new DataWrite();
        public bool Add(User_Table user_Table, out string messageStr)
        {
            messageStr = "";
            bool isSuccess = false;
            if (user_Table.Login_record != 0)
            {
                dataWrite.AddLogin_record(user_Table);
                isSuccess = true;
                //if (userDB.Equals(userInfo))
                //{
                //    userDB.AddUser(userInfo);
                //    isSuccess = true;
                //}
                //else
                //{
                //    messageStr = "有相同的值";
                //}
            }
            else
            {
                messageStr = "不能为空";
            }
            return isSuccess;
        }
    }    //写入登陆次数验证
    public class AddUser_document
    {
        private DataWrite dataWrite = new DataWrite();
        public bool Add(User_Document user_Document,out string messageStr)
        {
            messageStr = "";
            bool isSuccess = false;
            if (user_Document.Doc_head.Trim().Length != 0)
            {
                dataWrite.AddDocument(user_Document);
                isSuccess = true;
            }
            else
            {
                messageStr = "不能为空";
            }
            return isSuccess;
        }
    }
}

-----------LoginManger.cs类----------- 

2、DAL 数据交换层

(1)AEScook.cs类

用于登录密码加密解密数

源码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Threading.Tasks;

namespace DAL { 

    public class AEScook
    {
        /// <summary>
        /// AES加密
        /// </summary>
        /// <param name="text">加密字符</param>
        /// <param name="password">加密的密码</param>
        /// <param name="iv">密钥</param>
        /// <returns></returns>
        public string AESEncrypt(string text, string password, string iv)
        {
            RijndaelManaged rijndaelCipher = new RijndaelManaged();
            rijndaelCipher.Mode = CipherMode.CBC;
            rijndaelCipher.Padding = PaddingMode.PKCS7;
            rijndaelCipher.KeySize = 128;
            rijndaelCipher.BlockSize = 128;
            byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(password);
            byte[] keyBytes = new byte[16];
            int len = pwdBytes.Length;
            if (len > keyBytes.Length) len = keyBytes.Length;
            System.Array.Copy(pwdBytes, keyBytes, len);
            rijndaelCipher.Key = keyBytes;
            byte[] ivBytes = System.Text.Encoding.UTF8.GetBytes(iv);
            rijndaelCipher.IV = new byte[16];
            ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
            byte[] plainText = Encoding.UTF8.GetBytes(text);
            byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);
            return Convert.ToBase64String(cipherBytes);
        }
        /// <summary>
        /// AES解密
        /// </summary>
        /// <param name="text"></param>
        /// <param name="password"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public string AESDecrypt(string text, string password, string iv)
        {
            RijndaelManaged rijndaelCipher = new RijndaelManaged();
            rijndaelCipher.Mode = CipherMode.CBC;
            rijndaelCipher.Padding = PaddingMode.PKCS7;
            rijndaelCipher.KeySize = 128;
            rijndaelCipher.BlockSize = 128;
            byte[] encryptedData = Convert.FromBase64String(text);
            byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(password);
            byte[] keyBytes = new byte[16];
            int len = pwdBytes.Length;
            if (len > keyBytes.Length) len = keyBytes.Length;
            System.Array.Copy(pwdBytes, keyBytes, len);
            rijndaelCipher.Key = keyBytes;
            byte[] ivBytes = System.Text.Encoding.UTF8.GetBytes(iv);
            rijndaelCipher.IV = ivBytes;
            ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
            byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
            return Encoding.UTF8.GetString(plainText);
        }
    }
}

-----------AEScook.cs类-----------

(2)DataWrite.cs类

数据库写入类,主要负责数据库的insert 和 Update 操作

  1 #region << 版 本 注 释 >>
  2 /*----------------------------------------------------------------
  3 * 项目名称 :DAL
  4 * 项目描述 :
  5 * 类 名 称 :DataWrite
  6 * 类 描 述 :
  7 * 所在的域 :AIRCOINST
  8 * 命名空间 :DAL
  9 * 机器名称 :AIRCOINST 
 10 * CLR 版本 :4.0.30319.42000
 11 * 作    者 :RenZe
 12 * 创建时间 :2019/5/11 23:29:17
 13 * 更新时间 :2019/5/11 23:29:17
 14 * 版 本 号 :v1.0.0.0
 15 *******************************************************************
 16 * Copyright @ RenZe 2019. All rights reserved.
 17 *******************************************************************
 18 //----------------------------------------------------------------*/
 19 #endregion
 20 using System;
 21 using System.Collections.Generic;
 22 using System.Linq;
 23 using System.Text;
 24 using System.Threading.Tasks;
 25 using System.Data;
 26 using System.Data.SqlClient;
 27 using Model;
 28 using DAL;
 29 using System.Configuration;
 30 using Microsoft.ApplicationBlocks.Data;
 31 
 32 namespace DAL
 33 {
 34     public class DataWrite
 35     {
 36         AEScook eScook = new AEScook();
 37 
 38 
 39         private string connString = ConfigurationManager.ConnectionStrings["connString"].ToString();
 40 
 41         /// <summary>
 42         /// 数据库写入
 43         /// </summary>
 44         /// <param name="user_Table">用户表</param>
 45         /// <returns></returns>
 46         public int AddUser(User_Table user_Table)
 47         //用户注册
 48         {
 49 
 50             string commandText = "insert into User_Table (UserName,NickName,Password,CreateDate,PwdDeed,Permission,Date_Of_Birth,Age,Sex,IDCard)values(@UserName,@NickName,@Password,@CreateDate,@PwdDeed,@Permission,@Date_Of_Birth,@Age,@Sex,@IDCard)"; //数据库写入
 51             SqlParameter[] paras = new SqlParameter[]
 52             {
 53                 #region 数据传值
 54                 new SqlParameter("@UserName",user_Table.UserName),
 55                 new SqlParameter("@NickName",user_Table.NickName),
 56                 new SqlParameter("@Password",user_Table.Password),
 57                 new SqlParameter("@CreateDate",user_Table.CreateDate),
 58                 new SqlParameter("@PwdDeed",user_Table.PwdDeed),
 59                 new SqlParameter("@Permission",user_Table.Permission),
 60                 new SqlParameter("@Date_Of_Birth",user_Table.Date_Of_Birth),
 61                 new SqlParameter("@Age",user_Table.Age),
 62                 new SqlParameter("@Sex",user_Table.Sex),
 63                 new SqlParameter("@IDCard",user_Table.IDCard)
 64                 #endregion 数据传值
 65             };
 66             return SqlHelper.ExecuteNonQuery(connString, CommandType.Text, commandText, paras);
 67         }
 68         /// <summary>
 69         /// 数据库写入
 70         /// </summary>
 71         /// <param name="user_Table">用户表</param>
 72         /// <returns></returns>
 73         public int AddLogin_record(User_Table user_Table)
 74         //升级插入每个用户登陆的次数
 75         {
 76             string commandText = "UPDATE User_Table SET  Login_record = @Login_record WHERE UserID = @UserID";
 77             SqlParameter[] paras = new SqlParameter[]
 78             {
 79                 #region 数据传值
 80                 new SqlParameter("@Login_record",user_Table.Login_record),
 81                 new SqlParameter("@UserID",user_Table.UserID)
 82                 #endregion 数据传值
 83             };
 84             return SqlHelper.ExecuteNonQuery(connString, CommandType.Text, commandText, paras);
 85         }
 86 
 87         /// <summary>
 88         /// 数据库写入
 89         /// </summary>
 90         /// <param name="user_Document">用户文档表</param>
 91         /// <returns></returns>
 92         public int AddDocument(User_Document user_Document)
 93         {
 94             string commandText = "insert into User_Document (Doc_head,Doc_brief_head,Doc_column,Doc_type,Doc_array,Doc_key,Doc_summary,Doc_author,Doc_source,Doc_Date,UserName,UserID)values(@Doc_head,@Doc_brief_head,@Doc_column,@Doc_type,@Doc_array,@Doc_key,@Doc_summary,@Doc_author,@Doc_source,@Doc_Date,@UserName,@UserID)";
 95             SqlParameter[] paras = new SqlParameter[]
 96             {
 97                 new SqlParameter("@Doc_head",user_Document.Doc_head),
 98                 new SqlParameter("@Doc_brief_head",user_Document.Doc_brief_head),
 99                 new SqlParameter("@Doc_column",user_Document.Doc_column),
100                 new SqlParameter("@Doc_type",user_Document.Doc_type),
101                 new SqlParameter("@Doc_array",user_Document.Doc_array),
102                 new SqlParameter("@Doc_key",user_Document.Doc_key),
103                 new SqlParameter("@Doc_summary",user_Document.Doc_summary),
104                 new SqlParameter("@Doc_author",user_Document.Doc_author),
105                 new SqlParameter("@Doc_source",user_Document.Doc_source),
106                 new SqlParameter("@Doc_Date",user_Document.Doc_Date),
107                 new SqlParameter("@UserName",user_Document.UserName),
108                 new SqlParameter("@UserID",user_Document.UserID)
109             };
110             return SqlHelper.ExecuteNonQuery(connString, CommandType.Text, commandText, paras);
111         }
112     }
113 }

-----------DataWrite.cs类-----------

(3)InquireData.cs类

主要用于数据库的select条件查询

源码如下:

  1 #region << 版 本 注 释 >>
  2 /*----------------------------------------------------------------
  3 * 项目名称 :DAL
  4 * 项目描述 :
  5 * 类 名 称 :InquireData
  6 * 类 描 述 :
  7 * 所在的域 :AIRCOINST
  8 * 命名空间 :DAL
  9 * 机器名称 :AIRCOINST 
 10 * CLR 版本 :4.0.30319.42000
 11 * 作    者 :RenZe
 12 * 创建时间 :2019/5/12 12:13:48
 13 * 更新时间 :2019/5/12 12:13:48
 14 * 版 本 号 :v1.0.0.0
 15 *******************************************************************
 16 * Copyright @ RenZe 2019. All rights reserved.
 17 *******************************************************************
 18 //----------------------------------------------------------------*/
 19 #endregion
 20 using System.Collections.Generic;
 21 using System.Linq;
 22 using System.Text;
 23 using System.Threading.Tasks;
 24 using System.Data;
 25 using System.Data.SqlClient;
 26 using System.Configuration;
 27 using System;
 28 
 29 namespace DAL
 30 {
 31     public class InquireData
 32     {
 33         private string connString = ConfigurationManager.ConnectionStrings["connString"].ToString();
 34 
 35         /// <summary>
 36         ///  登陆验证并查询
 37         /// </summary>
 38         /// <param name="NickName">用户名</param>
 39         /// <param name="Password">密 码</param>
 40         /// <returns></returns>
 41         public Model.User_Table select_Usert(string NickName, string Password)
 42         {
 43             using (SqlConnection conn = new SqlConnection(connString))
 44             {
 45                 SqlCommand cmd = conn.CreateCommand();
 46                 cmd.CommandText = @"select UserID,UserName,NickName,Password from User_Table where NickName=@NickName and Password=@Password";
 47                 cmd.CommandType = CommandType.Text;
 48                 cmd.Parameters.Add(new SqlParameter(@"NickName", NickName));
 49                 cmd.Parameters.Add(new SqlParameter(@"Password", Password));
 50                 conn.Open();
 51                 SqlDataReader reader = cmd.ExecuteReader();
 52                 Model.User_Table user_Table = null;
 53                 while (reader.Read())
 54                 {
 55                     if (user_Table == null)
 56                     {
 57                         user_Table = new Model.User_Table();
 58                     }
 59                     user_Table.UserID = reader.GetInt32(0);
 60                     user_Table.UserName = reader.GetString(1).ToString();
 61                     user_Table.NickName = reader.GetString(2).ToString();
 62                     user_Table.Password = reader.GetString(3).ToString();
 63                 }
 64                 return user_Table;
 65             }
 66         } //用户登陆
 67         public Model.User_Table select_Userts(string UserID, string UserName)
 68         {
 69 
 70             using (SqlConnection conn = new SqlConnection(connString))
 71             {
 72                 SqlCommand cmd = conn.CreateCommand();
 73                 cmd.CommandText = "select UserID,UserName,NickName,Sex,IDCard,Date_Of_Birth from User_Table where UserID=@UserID and UserName=@UserName";
 74                 cmd.CommandType = CommandType.Text;
 75                 cmd.Parameters.Add(new SqlParameter(@"UserID", UserID));
 76                 cmd.Parameters.Add(new SqlParameter(@"UserName", UserName));
 77                 conn.Open();
 78                 SqlDataReader reader = cmd.ExecuteReader();
 79                 Model.User_Table user_Table = null;
 80                 while (reader.Read())
 81                 {
 82                     if (user_Table == null)
 83                     {
 84                         user_Table = new Model.User_Table();
 85                     }
 86                     user_Table.UserID = reader.GetInt32(0);
 87                     user_Table.UserName = reader.GetString(1).ToString();
 88                     user_Table.NickName = reader.GetString(2).ToString();
 89                     user_Table.Sex = reader.GetString(3).ToString();
 90                     user_Table.IDCard = reader.GetString(4).ToString();
 91                     user_Table.Date_Of_Birth = reader.GetDateTime(5);
 92                 }
 93                 return user_Table;
 94             }
 95         }  //获取个人信息
 96         public Model.Menu_Table Select_Menu(string 次级, string 应用程序ID, string 顺序)
 97         {
 98             using (SqlConnection conn = new SqlConnection(connString))
 99             {
100                 SqlCommand cmd = conn.CreateCommand();
101                 cmd.CommandText = @"select * from 菜单项 where @级次 = 2 and @应用程序ID=-1 order by 顺序";
102                 cmd.CommandType = CommandType.Text;
103                 cmd.Parameters.Add(new SqlParameter(@"次级", 次级));
104                 cmd.Parameters.Add(new SqlParameter(@"应用程序ID", 应用程序ID));
105                 cmd.Parameters.Add(new SqlParameter("顺序", 顺序));
106                 conn.Open();
107                 SqlDataReader reader = cmd.ExecuteReader();
108                 Model.Menu_Table menu_Table = null;
109                 while (reader.Read())
110                 {
111                     if (menu_Table == null)
112                     {
113                         menu_Table = new Model.Menu_Table();
114                     }
115                     menu_Table.菜单项ID = reader.GetInt32(0);
116                     menu_Table.级次 = reader.GetInt32(1);
117                     menu_Table.顺序 = reader.GetInt32(1);
118                 }
119                 return menu_Table;
120             }
121         } //菜单项
122         public Model.User_Table SelectLogin_record(string UserID,string Login_record)
123         {
124             using (SqlConnection conn = new SqlConnection(connString))
125             {
126                 SqlCommand cmd = conn.CreateCommand();
127                 cmd.CommandText = @"select UserID,Login_record from User_Table where Login_record=@Login_record";
128                 cmd.CommandType = CommandType.Text;
129                 cmd.Parameters.Add(new SqlParameter(@"Login_record", Login_record));
130                 conn.Open();
131                 SqlDataReader reader = cmd.ExecuteReader();
132                 Model.User_Table user_Table = null;
133                 while (reader.Read())
134                 {
135                     if (user_Table == null)
136                     {
137                         user_Table = new Model.User_Table();
138                     }
139                     user_Table.UserID = reader.GetInt32(0);
140                     user_Table.Login_record = reader.GetInt32(1);
141                 }
142                 return user_Table;
143             }
144         } //获取登陆次数
145     }
146 }

-----------InquireData.cs类-----------

(4)SQLHelper.cs类 

此类是MSDN官方类,里面包含数十种数据库操作<本人已经成功汉化,部分未汉化>

源码如下:

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

-----------SLQHelp.cs-----------

 3、Model 实体类

  Model是什么?它什么也不是!它在三层架构中是可有可无的。它其实就是面向对象编程中最基本的东西:类。一个桌子是一个类,一条新闻也是一个类,int、string、doublie等也是类,它仅仅是一个类而已。
这样,Model在三层架构中的位置,和int,string等变量的地位就一样了,没有其它的目的,仅用于数据的存储而已,只不过它存储的是复杂的数据。所以如果你的项目中对象都非常简单,那么不用Model而直接传递多个参数也能做成三层架构。
那为什么还要有Model呢,它的好处是什么呢。下面是思考一个问题时想到的,插在这里:
Model在各层参数传递时到底能起到做大的作用?
在各层间传递参数时,可以这样:
AddUser(userId,userName,userPassword,…,)
也可以这样:
AddUser(userInfo)
这两种方法那个好呢。一目了然,肯定是第二种要好很多。
什么时候用普通变量类型(int,string,guid,double)在各层之间传递参数,什么使用Model传递?下面几个方法:
SelectUser(int UserId)
SelectUserByName(string username)
SelectUserByName(string username,string password)
SelectUserByEmail(string email)
SelectUserByEmail(string email,string password)
可以概括为:
SelectUser(userId)
SelectUser(user)
这里用user这个Model对象囊括了username,password,email这三个参数的四种组合模式。UserId其实也可以合并到user中,但项目中其它BLL都实现了带有id参数的接口,所以这里也保留这一项。
传入了userInfo,那如何处理呢,这个就需要按照先后的顺序了,有具体代码决定。
这里按这个顺序处理
首先看是否同时具有username和password,然后看是否同时具有email和password,然后看是否有username,然后看是否有email。依次处理。
这样,如果以后增加一个新内容,会员卡(number),则无需更改接口,只要在DAL的代码中增加对number的支持就行,然后前台增加会员卡一项内容的表现与处理即可。

(1)Sql_Datatable.cs类:

源码如下:

#region << 版 本 注 释 >>
/*----------------------------------------------------------------
* 项目名称 :Model
* 项目描述 :
* 类 名 称 :Sql_Datatable
* 类 描 述 :
* 所在的域 :AIRCOINST
* 命名空间 :Model
* 机器名称 :AIRCOINST 
* CLR 版本 :4.0.30319.42000
* 作    者 :RenZe
* 创建时间 :2019/5/11 23:08:16
* 更新时间 :2019/5/11 23:08:16
* 版 本 号 :v1.0.0.0
*******************************************************************
* Copyright @ RenZe 2019. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/
#endregion
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System;
using System.Threading.Tasks;

namespace Model
{
    /// <summary>
    /// 菜单项
    /// </summary>
    public class Menu_Table
    {
        public int 菜单项ID { get; set; }
        public string 菜单项名称 { get; set; }
        public string 操作集合 { get; set; }
        public string 菜单项编号 { get; set; }
        public string 角色ID { get; set; }
        public string 窗体路径 { get; set; }
        public bool 是否无权时隐藏 { get; set; }
        public int 级次 { get; set; }
        public int 顺序 { get; set; }
        public string 进入时图标 { get; set; }
        public string 离开时图标 { get; set; }
        public int 应用程序ID { get; set; }
        public int 所属菜单项ID { get; set; }
    }
    /// <summary>
    /// 用户
    /// </summary>
    public class User_Table
    {
        //用户ID (用于其他关联)
        public int UserID { get; set; } 

        //用户名
        public string UserName { get; set; } 

        //姓名
        public string NickName { get; set; } 

        //身份证
        public string IDCard { get; set; } 

        //密码
        public string Password { get; set; } 

        //注册日期
        public DateTime CreateDate { get; set; } 

        //密码种子(用于找回密码)
        public string PwdDeed { get; set; } 

        //用户权限 (其中1为管理员,其中2为领导,其中3为职员) (用于其他关联)
        public string Permission { get; set; } 

        //出生日期
        public DateTime Date_Of_B { get; set; }  

        //年龄
        public string Age { get; set; } 

        //性别
        public string Sex { get; set; } 

        //登陆记录
        public int Login_record { get; set; } 
    }

    /// <summary>
    /// 文件上传
    /// </summary>
    public class User_UpFile
    {
        //上传文件ID
        public int UpFileID { get; set; }

        //文件名
        public string File_Name { get; set; }

        //文件路径
        public string File_Path { get; set; }

        //用户名  ---  关联用户名
        public string UserName { get; set; }

        //用户ID  ---  关联用户ID
        public string UserID { get; set; } 
    }
    /// <summary>
    /// 文档记录
    /// </summary>
    public class User_Document
    {
        //文档ID
        public int DocID { get; set; }

        //文章标题
        public string Doc_head { get; set; }

        //文章简略标题
        public string Doc_brief_head { get; set; }

        //分类栏目
        public string Doc_column { get; set; }

        //文章类型
        public string Doc_type { get; set; }

        //文档排序
        public string Doc_array { get; set; }

        //文档关键字
        public string Doc_key { get; set; }

        //文档摘要
        public string Doc_summary { get; set; }

        //作者
        public string Doc_author { get; set; }

        // 文档来源
        public string Doc_source { get; set; }

        //创建日期
        public DateTime Doc_Date { get; set; }

        //用户名   ---  关联用户名
        public string UserName { get; set; }

        //用户ID  ---  关联用户ID
        public string UserID { get; set; } 


    }
}

--------Sql_Datatable.cs---------

4、UI层 显示层

UI层就是网站的根目录,包含网页,及网页根目录

目录如图上图所示↑

其中重要的为Web.Config文件

对于我而言主要用来链接数据库使用

链接数据库命令如下:

1 <connectionStrings>
2     <add name="connString" connectionString="Data Source=.;Initial Catalog=你的数据库名称;uid=你的数据库用户名;pwd=你的密码;" providerName="System.Data.SqlClient" />
3   </connectionStrings>

本人开发数据库版本为SQL 2008 R2  

解释如下:connString 为DAL 操作层链接数据库模块的字段 

Data Source = . 为数据库服务器 默认本机数据库为"."

Initial Catalog =WebDate 链接的数据名

uid=sa 链接数据库用户名

pwd=rzt123!@#; 链接数据库密码

猜你喜欢

转载自www.cnblogs.com/MineLSG/p/11110934.html
今日推荐