ADO.NET学習ノート(12)DataSetをさらにカプセル化

7903 ワード

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=connStrd=connnStr));using(SqlCommand cmd=connnn=connStrn(SqlCommand);using(SqlCommand=connc. 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はポインタ(カーソル)を1つ置くことに相当し、現在のカーソルが指す行のみを読み取ることができ、接続が切断されると再読み込みできません.このような利点は、クエリの結果がどれだけあっても、プログラムが使用するメモリにほとんど影響を与えないことです.
解決策: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を使い終えなければならない.