关于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。