質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.04%

このコマンドに関連付けられている DataReader が既に開かれています。 このコマンドを最初に閉じる必要があります。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 3,770

syosinn

score 12

 エラー

初心者です。
このコマンドに関連付けられている DataReader が既に開かれています。 このコマンドを最初に閉じる必要があります。というエラーが取れず、困っています。

下はDB接続クラスです。

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EmployeeSystem.DataAccess
{
    class DBManager
    {
        private SqlConnection sqlConnection;
        private SqlTransaction sqlTransaction;


        /// <summary>
        /// DB接続
        /// </summary>
        public DBManager()
        {
            // 接続文字列を生成
            String connectionString = ConfigurationManager.ConnectionStrings["sqlsvr"].ConnectionString;

            // SqlConnection の新しいインスタンスを生成 (接続文字列を指定)
            this.sqlConnection = new SqlConnection(connectionString);

            // データベース接続を開く
            this.sqlConnection.Open();
        }

        /// <summary>
        /// DB切断
        /// </summary>
        public void Close()
        {
            this.sqlConnection.Close();
            this.sqlConnection.Dispose();
        }

        /// <summary>
        /// トランザクション開始
        /// </summary>
        public void BeginTran()
        {
            this.sqlTransaction = this.sqlConnection.BeginTransaction();
        }

        /// <summary>
        /// トランザクション コミット
        /// </summary>
        public void CommitTran()
        {
            if (this.sqlTransaction.Connection != null)
            {
                this.sqlTransaction.Commit();
                this.sqlTransaction.Dispose();
            }
        }

        /// <summary>
        /// トランザクション ロールバック
        /// </summary>
        public void RollBack()
        {
            if (this.sqlTransaction.Connection != null)
            {
                this.sqlTransaction.Rollback();
                this.sqlTransaction.Dispose();
            }
        }
        /// <summary>
        /// クエリ実行(戻り値なし)
        /// </summary>
        /// <param name="query"></param>
        /// <param name="paramDict"></param>
        public void ExecuteVoidQuery(string query,Dictionary<string, object> paramDict)
        {
            SqlCommand command = new SqlCommand();

            //クエリー送信先、トランザクションの指定
            command.Connection = this.sqlConnection;
            command.Transaction = this.sqlTransaction;

            command.CommandText = query;
            foreach (KeyValuePair<string, Object> item in paramDict)
            {
                command.Parameters.Add(new SqlParameter(item.Key, item.Value));
            }

            // SQLを実行
            SqlDataReader reader = command.ExecuteReader();

        }
        /// <summary>
        /// クエリ実行(output項目あり)
        /// </summary>
        /// <param name="query"></param>
        /// <param name="paramDict"></param>
        /// <returns></returns>
        public SqlDataReader ExecuteQuery(string query, Dictionary<string, Object> paramDict)
        {
            SqlCommand command = new SqlCommand();

            //クエリー送信先、トランザクションの指定
            command.Connection = this.sqlConnection;
            command.Transaction = this.sqlTransaction;

            command.CommandText = query;
            foreach (KeyValuePair<string, Object> item in paramDict)
            {
                command.Parameters.Add(new SqlParameter(item.Key, item.Value));
            }

            // SQLを実行
            SqlDataReader reader = command.ExecuteReader();

            return reader;
        }

        /// <summary>
        /// クエリー実行(OUTPUT項目あり)
        /// <para name="query">SQL文</para>
        /// </summary>
        public SqlDataReader ExecuteQuery(string query)
        {
            return this.ExecuteQuery(query, new Dictionary<string, Object>());
        }

        /// <summary>
        /// クエリー実行(OUTPUT項目なし)
        /// <para name="query">SQL文</para>
        /// <para name="paramDict">SQLパラメータ</para>
        /// </summary>
        public void ExecuteNonQuery(string query, Dictionary<string, Object> paramDict)
        {
            SqlCommand sqlCom = new SqlCommand();

            //クエリー送信先、トランザクションの指定
            sqlCom.Connection = this.sqlConnection;
            sqlCom.Transaction = this.sqlTransaction;

            sqlCom.CommandText = query;
            foreach (KeyValuePair<string, Object> item in paramDict)
            {
                sqlCom.Parameters.Add(new SqlParameter(item.Key, item.Value));
            }

            // SQLを実行
            sqlCom.ExecuteNonQuery();
        }

        /// <summary>
        /// DataLoad
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public DataTable DataLoad(SqlDataReader reader)
        { 
            DataTable dt = new System.Data.DataTable();
            dt.Load(reader);
            return dt;
        }

    }
}

下のコードは呼び出し元です

 if (result == DialogResult.Yes)
                {
                    String data = dataGridView1.CurrentRow.Cells[0].Value.ToString();
                    String Namedata = dataGridView1.CurrentRow.Cells[1].Value.ToString();
                    DBManager dBManager = new DBManager();
                    {
                        try
                        {


                            // SQLの設定
                            string DeleteSql = "DELETE FROM PostList where PostCode = @postCode and PostName = @postName;";


                            Dictionary<String, Object> param = new Dictionary<string, Object>();
                            param.Add("@postCode", data.ToString());
                            param.Add("@postName", Namedata.ToString());
                            // データベースの接続開始
                            dBManager.BeginTran();
                            dBManager.ExecuteVoidQuery(DeleteSql, param);
                            dBManager.CommitTran();

                            MessageBox.Show("正常終了");
                            PostData();
                        }
                        catch (Exception exception)
                        {
                            dBManager.RollBack();
                            MessageBox.Show("異常終了"+exception.Message);
                        }
                        finally
                        {
                            // データベースの接続終了
                            dBManager.Close();

                        }

                    }
                }
                else
                {
                    MessageBox.Show("処理を中断しました");

                }


この呼び出し元の

dBManager.CommitTran();


を実行すると、上のエラーが出ます。
初歩的な質問で申し訳ありませんが、教えて頂きたいです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

トランザクションのコミットを行う際にDataReaderが閉じられていない為に発生していると思われます。
通常、DELETE文を実行するのであれば、ExecuteNonQueryを使用する形になるかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/06 13:44

    ありがとうございます。
    無事出来ました。
    またよろしくお願いします。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • C#に関する質問
  • このコマンドに関連付けられている DataReader が既に開かれています。 このコマンドを最初に閉じる必要があります。