ADO.NET 学习笔记(十二) DataSet进一步封装

关于ExecuteReader(string sqlMessage, params SqlParameter[] parameters)方法的定义

class SQLHelper
{
  //ExecuteReader方法:
  public static SqlDataReader ExecuteReader(string sqlMessage, params SqlParameter[] parameters)
  {
    string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
    using (SqlConnection conn = new SqlConnection(connStr))
    {
      conn.Open();
      using (SqlCommand cmd = conn.CreateCommand())
      {
        cmd.CommandText = sqlMessage;
        foreach (SqlParameter myParameter in parameters)
        {
          cmd.Parameters.Add(myParameter);
        }
        return cmd.ExecuteReader();
      }
    }
  }
}

尝试调用ExecuteReader(string sqlMessage, params SqlParameter[] parameters)方法

private void btnExecuteReader_Click(object sender, EventArgs e)
{
  using (SqlDataReader myReader = SQLHelper.ExecuteReader("select * From T_Person"))
  {
    while(myReader.Read())
    {
      MessageBox.Show(myReader.GetString(myReader.GetOrdinal("FName")) + "\t" + myReader.GetString(myReader.GetOrdinal("FAge")));
    }
  }
  MessageBox.Show("遍历完成");
}

运行上面的代码,程序运行错误。

错误提示:阅读器关闭时尝试调用Read无效

using(SqlDataReader myReader=SQLHelper.ExecuteReader("select * From T_Person"))
--->
public static SqlDataReader ExecuteReader(string sqlMessage, params SqlParameter[] parameters)
{
  string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
  using (SqlConnection conn = new SqlConnection(connStr))
  {
    conn.Open();
    using (SqlCommand cmd = conn.CreateCommand())
    {
      cmd.CommandText = sqlMessage;
      foreach (SqlParameter myParameter in parameters)
      {
        cmd.Parameters.Add(myParameter);
      }
      return cmd.ExecuteReader();
    }
  }
}
当执行return cmd.ExecuteReader()后执行了conn.close和conn.dispose连接被关闭,在此之后无法执行reader.Read()语句

这里变量reader是SqlDataReader类型,SqlDataReader中的查询结果并不是放到程序中的,而是放在数据库服务器中,SqlDataReader只是相当于放了一个指针(游标),只能读取当前游标指向的行,一旦连接断开就不能再读取。这样做的好处就是无论查询结果有多少条,对程序占用的内存都几乎没有影响。

解决方案:
ADO.Net中提供了数据集的机制,将查询结果填充到本地内存中,这样即使连接断开或服务器断开都不会影响数据的读取。
DataSet包含若干个DataTable
DataTable包含若干行DataTable.Rows[i]

注意事项:
DataSet只能存储少量数据,返回的结果集如果数据量过大,则会对内存产生巨大负担,因此DataSet只适合小数据量,大数据量仍然使用SqlDataReader。

 1 public static DataTable ExecuteDataTable(string sqlMessage, params SqlParameter[] parameters)

 2 {

 3   string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;

 4   using (SqlConnection conn = new SqlConnection(connStr))

 5   {

 6     conn.Open();

 7     using (SqlCommand cmd = conn.CreateCommand())

 8     {

 9       cmd.CommandText = sqlMessage;

10       foreach (SqlParameter myParameter in parameters)

11       {

12         cmd.Parameters.Add(myParameter);

13       }

14       DataSet myDataSet = new DataSet();

15       SqlDataAdapter myAdapter = new SqlDataAdapter(cmd);

16       myAdapter.Fill(myDataSet);

17       return myDataSet.Tables[0];

18     }

19   }

20 }

调用ExecuteDataTable(string sqlMessage, params SqlParameter[] parameters)方法

 1 private void btnExecuteDataTabel_Click(object sender, EventArgs e)

 2 {

 3   DataTable myDataTable = SQLHelper.ExecuteDataTable("select * From T_Person");

 4   for (int i = 0; i < myDataTable.Rows.Count;i++ )

 5   {

 6     DataRow myRow = myDataTable.Rows[i];

 7     MessageBox.Show(Convert.ToString(myRow["FName"]) + "\t" +     Convert.ToInt32(myRow["FAge"]));

 8   }

 9   MessageBox.Show("遍历完成");

10 }

注意事项

一、SqlParameter的参数
SQLHelper.ExecuteDataTable("select * from T_Person where FId=@Id",new SqlParameter("Id",0));

错误提示:参数化查询'(@Id bigint)select * from T_Users where Id=@Id'需要参数'@Id',但未提供该参数。

错误原因:构造函数匹配错误

解决方案:
SQLHelper.ExecuteDataTable("select * from T_Person where FId=@Id",new SqlParameter("Id",(object)0));

二、SqlConnection在程序中是否可以保持open的状态

答案:不可以,因为任何一个数据库承载的链接都是有限的,一旦数据库链接数满载就不能再链接。即对于数据库来说,链接是非常宝贵的资源,一定要使用完就Close、Dispose。

你可能感兴趣的:(.net)