C# SqlHelper 详解(自己总结)

C# SqlHelper 详解(自己总结)

码农世界 2024-06-13 后端 81 次浏览 0个评论

序言

数据库是我们常用的存储数据的容器,网上有很多关于SqlHelper 类库,里面有的写的很复杂很详细(有点冗余),有很多方法基本上用不到,所以自己根据很多的项目实践总结了一套适合自己的SqlHelper 类 包括 数据库的增、删、改、查、存储过程、事务等,以便后续使用,希望能给诸君有些帮助,如有错误麻烦请指出并纠正。

数据库的创建

  • 创建一个银行信息数据

    use master

    --- 判断 系统是否有数据库

    if exists(select * from sys.databases where name = 'DBBank')

         drop database DBBank

    --- 创建数据库

    create database DBBank

    on ---数据文本

    (

         name = 'DBBank',    --逻辑名称

         filename = 'D:\C#\CommonLib\SQL\Data\DBBank.mdf',   --物理路径和名称

         size = 5MB,    -- 文件的初始大小

         filegrowth = 2MB   --文件的增长方式可以写大小,也可以写百分比

    )

    log on

    (

       name = 'DBBank_log',

       filename = 'D:\C#\CommonLib\SQL\Data\DBBank_log.ldf',  --日志后缀 .ldf

       size = 5MB,

       filegrowth = 2MB

    )

    go

    • 创建 三个表 AccountInfo 账户信息表   BankCard 银行卡表   BankCard 转账信息表

      use DBBank

      -- 判断 表 AccountInfo 是否存在

      if exists(select * from sys.objects where  name = 'AccountInfo' and type = 'U')

           drop table AccountInfo

      go

      Create table AccountInfo   --建表  账户信息表

      (

           AccountId int primary key,    --账户Id 主键

           AccountCode varchar(20) check(len(AccountCode) = 18) unique,   -- 身份证号码 检查长度并且唯一

           AccountPhone varchar(11) check(len(AccountPhone) = 11),        --电话号码

           RealName nvarchar(10) not null,            --姓名

           OpenTime smalldatetime default(getdate())  --开户时间

      )

      if exists(select * from sys.objects where name = 'BankCard' and type = 'U')

           drop table BankCard

      create table BankCard      --创建 银行卡表

      (

           CardNo varchar(30) primary key ,     ---创建卡号 主键

           AccountId int not null,                   --账户编号(与账户信息表形成外键关系)

           CardPwd varchar(20) not null,      --账户密码

           CardMoney money check(CardMoney >= 0) NOT NULL,     --余额

           CardTime smalldatetime default(getdate())    --建卡时间

      )

      if exists(select * from sys.objects where name = 'CardExchange' and type = 'U')

           drop table CardExchange

      create table CardExchange     --创建 转账信息表

      (

           ExchangeId int primary key identity(1,1),     --交易自动编号

           CardNo varchar(30) not null,    --银行卡号

           MoneyInBank money ,    --存钱金额

           MoneyOutBank money,   --取钱金额

           ExchangeTime smalldatetime default(getdate())    --交易时间

      )

      • 表关系图

        C# SqlHelper 详解(自己总结)

        SqlHelper类库编写

        • 新建一个类库 DbUtility

          C# SqlHelper 详解(自己总结)

          在类库中新建一个类 SqlHelper

          C# SqlHelper 详解(自己总结)

          二、连接字符串

          ///

          /// 连接字符串

          ///

          private static readonly string connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;

          其中ConfigurationManager 需要添加引用

          C# SqlHelper 详解(自己总结)

          三 在SqlHelper类中编写增、删、改通用方法

          3.1 在SqlHelper 类中编写增、删、改通用方法

           ///

          /// 通用的增删改操作(普通的格式化SQL语句、带参数SQL语句、是否是存储过程)

          ///

          /// SQL语句/存储过程名字

          /// 存储过程

          /// 参数

          ///

          public static int ExecuteNonQuery(string sql,bool isProcedure = false, params SqlParameter[] paras)

          {

              //select @@Identity 返回上一次插入记录时自动产生的ID

              int result = 0;

              SqlConnection conn = new SqlConnection(connStr);  //连接字符串

              try

              {

                  if(conn == null)

                      throw new ArgumentNullException("连接对象不能为空!");

                  SqlCommand cmd = new SqlCommand(sql, conn);

                  if(isProcedure)

                      cmd.CommandType = CommandType.StoredProcedure;   //SqlCommand 设置成存储过程

                  if (conn.State == ConnectionState.Closed)

                      conn.Open();   //打开数据库               

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

                  {

                      cmd.Parameters.Clear(); //清空上一个数据

                      cmd.Parameters.AddRange(paras); //添加本次数据

                  }

                  result = cmd.ExecuteNonQuery();

              }

              catch (Exception ex)

              {

                  //如果有必要在这里写个记录日志

                  string errorMessage = "调用ExecuteNonQuery方法发生异常:"+ex.Message;

                  throw new Exception(errorMessage);

              }

              finally    //不管前面异常都会执行

              {

                  conn.Close();

              }

              return result;

          }

          1. 在WindowsFrom 测试
            1. 在新建一个WindowsFrom 测试程序

          C# SqlHelper 详解(自己总结)

          3.2.2  将Test 程序设置成 控制台应用程序

          C# SqlHelper 详解(自己总结)

              1. 在App.config 文件中添加 connectionStrings注意一定要按照截图格式写,不能有多余的空格**

          C# SqlHelper 详解(自己总结)

          白色圈部分 是连接数据库的 服务器名、数据库名、账户和密码。

              1. 添加类库引用

          C# SqlHelper 详解(自己总结)

              1. 测试SqlHelper 类中ExecuteNonQuery 方法
                1. SQL语句测试  向AccountInfo 增加一个开户信息

            ///

           /// SQL语句添加

           ///

           ///

           ///

           private void btnAdd_Click(object sender, EventArgs e)

           {

               string sql = "insert into AccountInfo(AccountId,AccountCode,AccountPhone,RealName,Opentime)values(1,'320833200010112222','12345678900','李*','2021-12-18')";

               int i = SqlHelper.ExecuteNonQuery(sql, false, null);

           }

          数据库中的结果

          C# SqlHelper 详解(自己总结)

                1. SQL语句+参数的方式  向CardBank增加一个银行卡信息

           ///

          /// SQL语句+参数

          ///

          ///

          ///

          private void btnAddParas_Click(object sender, EventArgs e)

          {

              string sql = "insert into BankCard(CardNo,AccountId,CardPwd,CardMoney,CardTime)values" +

                  "(@CardNo,@AccountId,@CardPwd,@CardMoney,@CardTime)";

              SqlParameter[] paras = new SqlParameter[]

              {

                  new SqlParameter("@CardNo","6225125478544111"),

                  new SqlParameter("@AccountId",1),   //注意 值类型不能为 0 ,如果是0 则需要装箱(object)0

                  new SqlParameter("@CardPwd","888888"),

                  new SqlParameter("@CardMoney",1000),

                  new SqlParameter("CardTime",DateTime.Now.ToString())

              };

              int i = SqlHelper.ExecuteNonQuery(sql, false, paras);

          }

          数据库中的结果

          C# SqlHelper 详解(自己总结)

                1. 存储过程  向AccountInfo 增加一个开户信息

          在数据库中创建一个存取记录信息的存储过程

          -----存储过程  也可以 proc    有参数输入无参数输出

          if exists(select * from sys.objects where name = 'proc_AddCardExchange')

               drop procedure proc_AddCardExchange

          go

          create procedure proc_AddCardExchange

          --存储过程输入参数的定义

          @CardNo varchar(30),

          @MoneyInBank money,

          @MoneyOutBank money,

          @ExchangeTime smalldatetime

          as

          ---添加交易记录

               insert into CardExchange(CardNo,MoneyInBank,MoneyOutBank,ExchangeTime)values(@CardNo,@MoneyInBank,@MoneyOutBank,@ExchangeTime)

          --- 跟新银行卡信息

               update BankCard set CardMoney = CardMoney + @MoneyInBank - @MoneyOutBank where CardNo = @CardNo

          go

          在WindowsFrom中测试

          ///

          /// 增加存储语句

          ///

          ///

          ///

          private void btnAddProc_Click(object sender, EventArgs e)

          {

              SqlParameter[] paras = new SqlParameter[]

              {

                  new SqlParameter("@CardNo","6225125478544111"),

                  new SqlParameter("@MoneyInBank",120),

                  new SqlParameter("@MoneyOutBank",(object)0),  //注意 值类型不能为 0 ,如果是0 则需要装箱成引用类型 (object)0

                  new SqlParameter("@ExchangeTime",DateTime.Now.ToString())

              };

              int i = SqlHelper.ExecuteNonQuery("proc_AddCardExchange",true,paras);  //sql 参数 存储过程名字

          }

          数据库中的结果

          C# SqlHelper 详解(自己总结)

                1. 存储过程 带参数返回值的存储过程

          在数据库中创建一个存取记录信息的存储过程 并返回卡余额和卡姓名

          -----存储过程  也可以 proc    有参数输入有参数输出

          if exists(select * from sys.objects where name = 'proc_AddCardExchangeShowUse')

               drop procedure proc_AddCardExchangeShowUse

          go

          create proc proc_AddCardExchangeShowUse

          --存储过程参数定义

          @CardNo varchar(30),

          @MoneyInBank money,

          @MoneyOutBank money,

          @ExchangeTime smalldatetime,

          @RealName nvarchar(10) output,

          @CardMoney money output

          as

               ---添加交易记录

               insert into CardExchange(CardNo,MoneyInBank,MoneyOutBank,ExchangeTime)values(@CardNo,@MoneyInBank,@MoneyOutBank,@ExchangeTime)

              --- 跟新银行卡信息

               update BankCard set CardMoney = CardMoney + @MoneyInBank - @MoneyOutBank where CardNo = @CardNo

               --- 获取输出参数

               select @CardMoney = BankCard.CardMoney, @RealName = AccountInfo.RealName from BankCard

               inner join AccountInfo on AccountInfo.AccountId = BankCard.AccountId

               where BankCard.CardNo = @CardNo

          go

          在WindowsFrom中测试

            ///

                  /// 增加存储语句 带参数输出

                  ///

                  ///

                  ///

                  private void btnAddProcOut_Click(object sender, EventArgs e)

                  {

                      SqlParameter outPar = new SqlParameter("@RealName", SqlDbType.NVarChar,10);  //字符一定要写明长度

                      SqlParameter outPar2 = new SqlParameter("@CardMoney", SqlDbType.Money);

                      outPar.Direction = ParameterDirection.Output;      //设置输出参数

                      outPar2.Direction = ParameterDirection.Output;

                      SqlParameter[] paras = new SqlParameter[]

                      {

                          new SqlParameter("@CardNo","6225125478544111"),

                          new SqlParameter("@MoneyInBank",80),

                          new SqlParameter("@MoneyOutBank",(object)0),  //注意 值类型不能为 0 ,如果是0 则需要装箱成引用类型 (object)0

                          new SqlParameter("@ExchangeTime",DateTime.Now.ToString()),

                          outPar,

                          outPar2

                      };

                      int i = SqlHelper.ExecuteNonQuery("proc_AddCardExchangeShowUse", true, paras); //sql 参数 存储过程名字

                      if (i >= 1)

                      {

                          string realName = outPar.Value.ToString();

                          double money = Convert.ToDouble(outPar2.Value);

                          Console.WriteLine("姓名:" + realName + "\t" + "余额:" + money);

                      }          

                  }

          测试结果

          C# SqlHelper 详解(自己总结)

          四 在SqlHelper类中编写查询方法

          4.1 SqlDataReader 查询  ExecuteReader

          ///

          /// 通用的查询操作 数据量比较大时使用 基本不占内存(推荐)

          ///

          /// SQL语句/存储过程名字

          /// 存储过程

          /// 参数

          ///

          public static SqlDataReader ExecuteReader(string sql, bool isProcedure = false, params SqlParameter[] paras)

          {

              SqlConnection conn = new SqlConnection(connStr);  //连接字符串

              SqlDataReader reader = null;

              try

              {

                  if (conn == null)

                      throw new ArgumentNullException("连接对象不能为空!");

                  SqlCommand cmd = new SqlCommand(sql, conn);

                  if (isProcedure)

                      cmd.CommandType = CommandType.StoredProcedure;   //SqlCommand 设置成存储过程

                  if (conn.State == ConnectionState.Closed)

                      conn.Open();   //打开数据库               

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

                  {

                      cmd.Parameters.Clear(); //清空上一个数据

                      cmd.Parameters.AddRange(paras); //添加本次数据

                  }

                  //在执行该命令时,如果关闭关联的DataReader对象,则关联的Connenction对象也将关闭。******

                  reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);

              }

              catch (Exception ex)

              {

                  //次处可以添加日志

                  string errorMessage = "调用ExecuteReader方法发生异常,具体异常信息:" + ex.Message;

                  conn.Close();

                  throw new Exception(errorMessage);

              }

              return reader;

          }

          4.1.1  在WindowsFrom中测试

          4.1.1.1  SQL语句

          ///

          /// SqlDataReader  + Sql

          ///

          ///

          ///

          private void btnReader_Click(object sender, EventArgs e)

          {

              string sql = "select * from BankCard";

              SqlDataReader reader = SqlHelper.ExecuteReader(sql, false);

              while(reader.Read())

              {

                  Console.WriteLine("卡号:" + reader["CardNo"] + "\t" + "余额:" + reader["CardMoney"]);

              }

              reader.Close();    //一定要关闭SqlDataReader

          }

          测试结果

          C# SqlHelper 详解(自己总结)

          4.1.1.2  SQL语句+参数测试

          ///

          /// SqlDataReader +Sql+Params

          ///

          ///

          ///

          private void btnReaderParms_Click(object sender, EventArgs e)

          {

              string sql = "select * from BankCard where CardNo = @CardNo";

              SqlParameter[] paras = new SqlParameter[]

              {

                  new SqlParameter("@CardNo","6225125478544111")

              };

              SqlDataReader reader = SqlHelper.ExecuteReader(sql,false, paras);

              while(reader.Read())

              {

                  Console.WriteLine("卡号:" + reader["CardNo"] + "\t" + "余额:" + reader["CardMoney"]);

              }

              reader.Close();     //一定要关闭SqlDataReader

          }

          测试结果

          C# SqlHelper 详解(自己总结)

          4.1.1.3  SQL语句+参数测试 多表查询   reader.NextResult()

          ///

          /// SqlDataReader +Sqls + Parama

          ///

          ///

          ///

          private void btnDataReaderParamss_Click(object sender, EventArgs e)

          {

              //注意*****两个语句连接用;

              string sql = "select * from BankCard where CardNo = @CardNo"+";"+ "select * from AccountInfo where AccountId = @AccountId";

              SqlParameter[] paras = new SqlParameter[]

              {

                  new SqlParameter("@CardNo","6225125478544111"),

                  new SqlParameter("@AccountId",1)

              };

              SqlDataReader reader = SqlHelper.ExecuteReader(sql, false, paras);

              while (reader.Read())

              {

                  Console.WriteLine("卡号:" + reader["CardNo"] + "\t" + "余额:" + reader["CardMoney"]);

              }

              if(reader.NextResult()) //跳转到下一个结果集(当读取批处理Transact-SQL 语句的结果时,使数据读取器前进到下一个结果)

              {

                  while(reader.Read())

                  {

                      Console.WriteLine("姓名:" + reader["RealName"]);

                  }

              }

              reader.Close();     //一定要关闭SqlDataReader

          }

          测试结果

          C# SqlHelper 详解(自己总结)

          4.1.1.4  存储过程

          4.1.1.4.1  在数据库中创建一个查询账户信息变化记录

          if exists(select * from sys.objects where name = 'proc_SelectCardExchangeParas')

               drop procedure proc_SelectCardExchangeParas

          go

          create procedure proc_SelectCardExchangeParas

          @CardNo varchar(30)

          as

               select CardNo,CardMoney from BankCard where CardNo = @CardNo

               select MoneyInBank,MoneyOutBank,ExchangeTime from CardExchange where CardNo = @CardNo

               select RealName from AccountInfo inner join BankCard on  AccountInfo.AccountId = BankCard.AccountId where BankCard.CardNo = @CardNo

          go

          4.1.1.4.2  在WF中编写查询程序

          ///

          /// 存储过程的查询 带参数 多表查询

          ///

          ///

          ///

          private void btnDataReaderProcParas_Click(object sender, EventArgs e)

          {

              string sql = "proc_SelectCardExchangeParas";

              SqlParameter[] paras = new SqlParameter[]

              {

                  new SqlParameter("@CardNo","6225125478544111")

              };

              SqlDataReader reader = SqlHelper.ExecuteReader(sql, true, paras);

              while (reader.Read())

              {

                  Console.WriteLine("卡号:" + reader["CardNo"] + "\t" + "余额:" + reader["CardMoney"]);

              }

              Console.WriteLine("************************华丽的分割线*****************************");

              if(reader.NextResult()) //跳转到下一个结果集(当读取批处理Transact-SQL 语句的结果时,使数据读取器前进到下一个结果)

              {

                  while(reader.Read())

                  {

                      Console.WriteLine("存钱:" + reader["MoneyInBank"] + "\t" + "取钱:" + reader["MoneyOutBank"] + "\t" + "交易时间:" + reader["ExchangeTime"]);

                  }

              }

              Console.WriteLine("************************华丽的分割线*****************************");

              if(reader.NextResult())

              {

                  while(reader.Read())

                  {

                      Console.WriteLine("姓名:" + reader["RealName"]);

                  }

              }

              reader.Close();     //一定要关闭SqlDataReader

          }

          测试结果

          C# SqlHelper 详解(自己总结)

          4.2  单一结果查询 ExecuteScalar() 返回第一行第一列,最大的特点是执行insert、update、delete时同时还执行查询

          ///

          /// 单一结果查询(第一行第一列)

          /// 最大特点就是执行insert、update、delete时同时还执行查询

          ///

          /// SQL语句/存储过程名字

          /// 存储过程

          /// 参数

          ///

          public static object ExecuteScalar(string sql, bool isProcedure = false, params SqlParameter[] paras)

          {

              SqlConnection conn = new SqlConnection(connStr);

              try

              {

                  if (conn == null)

                      throw new ArgumentNullException("连接对象不能为空!");

                  SqlCommand cmd = new SqlCommand(sql, conn);

                  if (isProcedure)

                      cmd.CommandType = CommandType.StoredProcedure;   //SqlCommand 设置成存储过程

                  if (conn.State == ConnectionState.Closed)

                      conn.Open();   //打开数据库                

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

                  {

                      cmd.Parameters.Clear(); //清空上一个数据

                      cmd.Parameters.AddRange(paras); //添加本次数据

                  }

                  return cmd.ExecuteScalar();

              }

              catch(Exception ex)

              {

                  //如果有必要在这里写个记录日志

                  string errorMessage = "调用ExecuteScalar方法发生异常:" + ex.Message;

                  throw new Exception(errorMessage);

              }

              finally

              {

                  conn.Close();

              }

          }

          4.2.1  在WF中测试

          4.2.1.1  单一结果查询

          ///

          /// 单一结果查询

          ///

          ///

          ///

          private void btnExecuteScalar_Click(object sender, EventArgs e)

          {

              string str = "select CardMoney from BankCard";

              object o = SqlHelper.ExecuteScalar(str,false,null);

              if (o != null)

              {

                  Console.WriteLine(o.ToString());

              }

          }

          测试结果

          C# SqlHelper 详解(自己总结)

          4.2.1.1  单一结果查询配合Insert into 一起使用

          ///

          /// 单一结果查询&Insert

          ///

          ///

          ///

          private void btnExecuteScalarAddInsert_Click(object sender, EventArgs e)

          {

              string sql = "insert into AccountInfo(AccountId,AccountCode,AccountPhone,RealName,Opentime)" +

                  "values(2,'320833200010116222','12345678922','小二','2022-12-19')" + ";" + "select count(*) from AccountInfo";

              object o = SqlHelper.ExecuteScalar(sql,false,null);

              Console.WriteLine((int)o);

          }

          测试结果

          C# SqlHelper 详解(自己总结)

          4.3  单表查询 GetDataTable 返回一张DataTable表

          ///

          /// 执行查询,查询结果填充到DataTable 只针对查询一个表的情况

          ///

          /// QL语句/存储过程名字

          /// 存储过程

          /// 参数

          /// DataTable

          public static DataTable GetDataTable(string sql, bool isProcedure = false, params SqlParameter[] paras)

          {

              DataTable dt = null;

              SqlConnection conn = new SqlConnection (connStr);

              try

              {

                  if (conn == null)

                      throw new ArgumentNullException("连接对象不能为空!");

                  SqlCommand cmd = new SqlCommand(sql, conn);

                  if (isProcedure)

                      cmd.CommandType = CommandType.StoredProcedure;   //SqlCommand 设置成存储过程

                  if (conn.State == ConnectionState.Closed)

                      conn.Open();   //打开数据库               

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

                  {

                      cmd.Parameters.Clear(); //清空上一个数据

                      cmd.Parameters.AddRange(paras); //添加本次数据

                  }

                  SqlDataAdapter da = new SqlDataAdapter(cmd);    //实例化一个数据库数据适配器类

                  dt = new DataTable();

                  da.Fill(dt);

                  cmd.Parameters.Clear();

              }

              catch (Exception ex)

              {

                  //如果有必要在这里写个记录日志

                  string errorMessage = "调用GetDataTable方法发生异常:" + ex.Message;

                  throw new Exception(errorMessage);

              }

              finally

              {

                  conn.Close();

              }

              return dt;

          }

          4.3.1  在WF中测试

          4.3.1.1  SQL语句获取DataTable

          ///

          /// SQL语句获取dateTable

          ///

          ///

          ///

          private void btnGetDataTableSQL_Click(object sender, EventArgs e)

          {

              string sql = "select * from AccountInfo";

              DataTable dt = SqlHelper.GetDataTable(sql, false, null);

              if (dt != null)

              {

                  foreach(DataRow dr in dt.Rows)

                  {

                      Console.WriteLine("名字:" + dr["RealName"].ToString() + "\t" + "身份证:" + dr["AccountCode"].ToString());

                  }              

              }

          }

          测试结果

          C# SqlHelper 详解(自己总结)

          4.3.1.2  SQL语句+参数 获取DataTable

          ///

          /// 参数的方式获取dateTable

          ///

          ///

          ///

          private void btnGetDataTableParams_Click(object sender, EventArgs e)

          {

              string sql = "select * from AccountInfo where AccountId >= @AccountId";

              SqlParameter[] paras = new SqlParameter[]

              {

                  new SqlParameter("@AccountId",2)

              };

              DataTable dt = SqlHelper.GetDataTable(sql,false,paras);

              if(dt != null)

              {

                  foreach(DataRow dr in dt.Rows)

                  {

                      Console.WriteLine("名字:" + dr["RealName"].ToString() + "\t" + "身份证:" + dr["AccountCode"].ToString());

                  }

              }

          }

          测试结果

          C# SqlHelper 详解(自己总结)

          4.3.1.3  存储语句+参数 获取DataTable

          ///

          /// 带参数的存储过程

          ///

          ///

          ///

          private void btnGetDataTableProcParas_Click(object sender, EventArgs e)

          {

              SqlParameter[] paras = new SqlParameter[]

              {

                  new SqlParameter("@CardNo","6225125478544111")

              };

              DataTable dt = SqlHelper.GetDataTable("proc_SelectCardExchangeParas", true, paras);

              if (dt != null)

              {

                  foreach (DataRow dr in dt.Rows)

                  {

                      Console.WriteLine("卡号:" + dr["CardNo"].ToString() + "\t" + "余额:" + dr["CardMoney"].ToString());

                  }

              }

          }

          测试结果

          C# SqlHelper 详解(自己总结)

          4.4  多表查询 GetDataSet 返回一张或多张DataTable表

          ///

          /// 执行查询,数据填充到DataSet(多个结果集)

          ///

          /// QL语句/存储过程名字

          /// 存储过程

          /// 参数

          /// DateSet

          ///

          public static DataSet GetDataSet(string sql, bool isProcedure = false, params SqlParameter[] paras)

          {

              DataSet ds = null;

              SqlConnection conn = new SqlConnection(connStr);

              try

              {

                  if (conn == null)

                      throw new ArgumentNullException("连接对象不能为空!");

                  SqlCommand cmd = new SqlCommand(sql, conn);

                  if (isProcedure)

                      cmd.CommandType = CommandType.StoredProcedure;   //SqlCommand 设置成存储过程

                  if (conn.State == ConnectionState.Closed)

                      conn.Open();   //打开数据库               

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

                  {

                      cmd.Parameters.Clear(); //清空上一个数据

                      cmd.Parameters.AddRange(paras); //添加本次数据

                  }

                  SqlDataAdapter da = new SqlDataAdapter(cmd);    //实例化一个数据库数据适配器类

                  ds = new DataSet();

                  da.Fill(ds);

                  cmd.Parameters.Clear();

              }

              catch (Exception ex)

              {

                  //如果有必要在这里写个记录日志

                  string errorMessage = "调用GetDataSet方法发生异常:" + ex.Message;

                  throw new Exception(errorMessage);

              }

              finally

              {

                  conn.Close();

              }

              return ds;

          }

          4.4.1  在WF中测试

          4.4.1.1  SQL语句获取DataSet

          ///

          /// GetSet

          ///

          ///

          ///

          private void btnGetSetSql_Click(object sender, EventArgs e)

          {

              string sql = "select * from AccountInfo" + ";" + "select * from BankCard";

              DataSet ds = SqlHelper.GetDataSet(sql);

              foreach(DataRow dr in ds.Tables[0].Rows)

              {

                  Console.WriteLine("名字:" + dr["RealName"].ToString() + "\t" + "身份证:" + dr["AccountCode"].ToString());

              }

              foreach(DataRow dr in ds.Tables[1].Rows)

              {

                  Console.WriteLine("卡号:" + dr["CardNo"].ToString() + "\t" + "余额:" + dr["CardMoney"].ToString());

              }

          }

          测试结果

          C# SqlHelper 详解(自己总结)

          4.5  多表查询 GetDataSet 返回一张或多张 包含DataTable表名

          ///

          /// 执行查询,数据填充到DataSet(多个结果集)返回带表名的DataSet

          ///

          /// 表名,Sql语句的字典

          ///

          ///

          public static DataSet GetDataSet(Dictionary sqlAndTableName)

          {

              SqlConnection conn = new SqlConnection(connStr);

              SqlCommand cmd = new SqlCommand();

              DataSet ds = null;

              try

              {

                  if (conn == null)

                      throw new ArgumentNullException("连接对象不能为空!");

                  if (conn.State == ConnectionState.Closed)

                      conn.Open();   //打开数据库

                  if (sqlAndTableName == null)

                      throw new ArgumentException("连接数据库字符串不能为空!");

                  cmd.Connection = conn;

                  SqlDataAdapter sd = new SqlDataAdapter(cmd);   实例化一个数据库数据适配器类

                  ds = new DataSet();       //实例化 DataSet

                  foreach(string tableName in sqlAndTableName.Keys)

                  {

                      cmd.CommandText = sqlAndTableName[tableName];

                      sd.Fill(ds,tableName);

                  }

                  return ds;

              }

              catch (Exception ex)

              {

                  //如果有必要在这里写个记录日志

                  string errorMessage = "调用GetDataSet方法发生异常:" + ex.Message;

                  throw new Exception(errorMessage);

              }

              finally

              {

                  conn.Close();

              }

          }

          4.5.1  在WF中测试

          4.5.1.1  SQL语句获取DataSet

          ///

          /// GetSetAndTableName

          ///

          ///

          ///

          private void btnGetSetSqlAndTableName_Click(object sender, EventArgs e)

          {

              string sql1 = "select * from AccountInfo";

              string sql2 = "select * from BankCard";

              Dictionary sqlAndTableName = new Dictionary()

              {

                  ["AccountInfo"] = sql1, //键 值

                  ["BankCard"] = sql2

              };

              DataSet ds = SqlHelper.GetDataSet(sqlAndTableName);

              foreach (DataRow dr in ds.Tables["AccountInfo"].Rows)

              {

                  Console.WriteLine("名字:" + dr["RealName"].ToString() + "\t" + "身份证:" + dr["AccountCode"].ToString());

              }

              foreach (DataRow dr in ds.Tables["BankCard"].Rows)

              {

                  Console.WriteLine("卡号:" + dr["CardNo"].ToString() + "\t" + "余额:" + dr["CardMoney"].ToString());

              }

          }

          测试结果

          C# SqlHelper 详解(自己总结)

          五 在SqlHelper类中编写事务方法

          5.1 在DbUtility类库中编写一个SQL语句类

          ///

          /// SQL语句类

          ///

          public class CommandInfo

          {

              ///

              /// sql或存储过程语句

              ///

              public string CommandText;//sql或存储过程名

              ///

              /// 参数列表

              ///

              public SqlParameter[] Paras; //参数列表

              ///

              /// 是否是存储过程

              ///

              public bool IsProcedure; //是否是存储过程

              public CommandInfo()

              {

              }

              ///

              /// 构造函数

              ///

              /// SQL语句

              /// 是否是存储过程

              public CommandInfo(string comText, bool isProcedure = false)

              {

                  this.CommandText = comText;

                  this.IsProcedure = isProcedure;

              }

              ///

              /// 构造函数

              ///

              /// SQL 语句

              /// 是否是存储过程

              /// 参数数组

              public CommandInfo(string sqlText, bool isProcedure = false, params SqlParameter[] paras)

              {

                  this.CommandText = sqlText;

                  this.Paras = paras;

                  this.IsProcedure = isProcedure;

              }

          }

          5.2 在SqlHelper类中 ExecuteTrans 事务方法

          调取事务需要5步骤

          1、开启事务   实例化事务

          2、将创建的SqlTransaction对象分配给要执行的SqlCommand的Transaction属性  

          3、调用相应的方法执行SqlCommand命令(循环调用)

          4、如果所有的sql命令都执行成功,则执行commit这个方法,提交事务

          5、如果执行异常回滚 Rollback()

          ///

          /// 事务 批量执行 CommandInfo 包括sql,脚本类型,参数列表 **********

          ///

          /// SQL语句类列表

          ///

          public static bool ExecuteTrans(List comList)

          {

              SqlConnection conn = new SqlConnection(connStr);

              SqlCommand cmd = new SqlCommand();

              SqlTransaction trans = null;          

              try

              {

                  if (conn == null)

                      throw new ArgumentNullException("连接对象不能为空!");

                  if (conn.State == ConnectionState.Closed)

                      conn.Open();   //打开数据库

                  if (comList == null)

                      throw new ArgumentNullException("连接语句不能为空!");

                  //1、开启事务

                  先实例SqlTransaction类,使用这个事务使用的是conn 这个连接,使用BeginTransaction这个方法来开始执行这个事务

                  trans = conn.BeginTransaction(); //执行数据库事务

                  //2、将创建的SqlTransaction对象分配给要执行的SqlCommand的Transaction属性              

                  cmd.Transaction = trans;

                  cmd.Connection = conn;

                  int count = 0;

                  for (int i = 0; i < comList.Count; i++)

                  {

                      //存储过程语句

                      //3、调用相应的方法执行SqlCommand命令

                      cmd.CommandText = comList[i].CommandText;

                      if (comList[i].IsProcedure)  //是存储过程

                          cmd.CommandType = CommandType.StoredProcedure;

                      else

                          cmd.CommandType = CommandType.Text; //语句

                      if (comList[i].Paras != null && comList[i].Paras.Length > 0)

                      {

                          cmd.Parameters.Clear();

                          foreach (var p in comList[i].Paras)

                          {

                              cmd.Parameters.Add(p);

                          }

                      }

                      count += cmd.ExecuteNonQuery();

                  }

                  //4、如果所有的sql命令都执行成功,则执行commit这个方法,执行这些操作

                  trans.Commit();

                  return true;

              }

              catch (Exception ex)

              {

                  //5、 异常回滚

                  trans.Rollback();

                  //如果有必要在这里写个记录日志

                  string errorMessage = "调用ExecuteTrans方法发生异常:" + ex.Message;

                  throw new Exception(errorMessage);

              }

              finally

              {

                  if (cmd.Transaction != null)

                      cmd.Transaction = null;    //清空事务

                  conn.Close();

              }

          }

          5.2.1  在WF中测试

          5.2.1.1  SQL语句事务

          ///

           /// SQL语句事务

           ///

           ///

           ///

           private void btnExecuteTransSql_Click(object sender, EventArgs e)

           {

               List cmdList = new List()

               {

                   new CommandInfo("update BankCard set CardMoney = CardMoney - 100 where CardNo = '6225125478544111'",false),

                   new CommandInfo("insert into CardExchange(CardNo,MoneyInBank,MoneyOutBank,ExchangeTime)values('6225125478544111',0,100,'2023-10-1')")

               };

               bool b = SqlHelper.ExecuteTrans(cmdList);

               Console.WriteLine(b);

           }

          测试结果

          C# SqlHelper 详解(自己总结)

          5.2.1.2  存储过程+带参数的SQL语句

          ///

          /// 存储过程& SQL+参数

          ///

          ///

          ///

          private void btnExecuteTransParasProc_Click(object sender, EventArgs e)

          {

              List cmdList = new List()

              {

                  new CommandInfo("insert into AccountInfo(AccountId,AccountCode,AccountPhone,RealName,Opentime)values(@AccountId,@AccountCode,@AccountPhone,@RealName,@Opentime)",

                      false, new SqlParameter[]

                      {

                          new SqlParameter("@AccountId",3),

                          new SqlParameter("@AccountCode","320833200010113333"),

                          new SqlParameter("@AccountPhone","12345678933"),

                          new SqlParameter("@RealName","张三"),

                          new SqlParameter("@OpenTime","2022-01-01")

                      }),  //SQL + 参数

                  new CommandInfo("proc_AddCardExchange", true, new SqlParameter[]

                  {

                      new SqlParameter("@CardNo","6225125478544111"),

                      new SqlParameter("@MoneyInBank",300),

                      new SqlParameter("@MoneyOutBank",(object)0),

                      new SqlParameter("@ExchangeTime","2024-01-01")

                  }),

              };

              bool b = SqlHelper.ExecuteTrans(cmdList);

              Console.WriteLine(b);

          }

          测试结果

          C# SqlHelper 详解(自己总结)

          总结

              数据库的SqlHelper类 主要由 增删改的 ExecuteNonQuery 方法, 查询的 ExecuteReader 方法(大数据读取)、ExecuteScalar 方法 读单一结果查询,同时可以执行增删改语句、GetDataTable 方法 单表查询、GetDataSet 方法多表查询 以及事务操作ExecuteTrans 方法组成, 写这篇文章的时候也重温了数据库的一些语法,以及对存储过程和事务有了更进一步的了解。虽然花了7-8个小时,但是收获颇丰。也给快要上一年级的小朋友做个表率。

转载请注明来自码农世界,本文标题:《C# SqlHelper 详解(自己总结)》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,81人围观)参与讨论

还没有评论,来说两句吧...

Top