C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: DB接続 どこでSqlConnectionをdispose


(過去ログ 119 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■69780 / inTopicNo.1)  DB接続 どこでSqlConnectionをdispose
  
□投稿者/ ブルー (6回)-(2014/01/29(Wed) 15:08:13)

分類:[C#] 

下記のようなコードがあります。内容は、データベースに接続して、接続成功・失敗を判定しています。
また、接続に成功したら、挿入処理をしようとしています。

MainFormからDBクラスを呼び出しています。

この時、どこで、どうやってSqlCoonectionをdisposeしてやればいいかわかりません。お教え頂けませんでしょうか?

DBクラスのConnectionDBメソッドの中で、

using (sqlConn = new SqlConnection(conStr))

とやれば、DBクラス内でdisposeできるのは理解できるのですが、それをやってしまうとInsertDB()でSqlCoonectionを利用できなくなってしまいます。
InsertDB()処理が終わった後に、SqlConnectionをdisposeする方法をお教え頂けませんでしょうか?

//=======================================================
//メインクラス

class MainForm{

private void ImpData_Click(object sender, EventArgs e)
{
try{
DB db = new DB();
db.ConnectionDB();
} catch(SqlConnection ex){
MessageBox.Show("失敗");
return;
}

MessageBox.Show("接続成功");

//この後に、データ挿入などの処理有り
db.InsertDB();
// この後にSqlConnectionをdisposeしたいです。

}
}

//=======================================================
//接続用クラス

class DB{

//DB接続文字列用変数
string conStr;

//接続変数
sqlConnection sqlConn;

public void ConnectionDB(){

conStr = "接続文字列";
sqlConn = new SqlConnection(conStr);

try{
sqlCon.Open();
} catch(SqlConnection ex){
sqlConn.Close();
MessageBox.Show("接続失敗");
}
}

public void InsertDB(){
//Insertの処理 ここでsqlConnを利用する
}

}
引用返信 編集キー/
■69781 / inTopicNo.2)  Re[1]: DB接続 どこでSqlConnectionをdispose
□投稿者/ shu (475回)-(2014/01/29(Wed) 15:17:20)
No69780 (ブルー さん) に返信

DBクラスのインスタンス作成では
接続情報だけ保存するようにして

InsertDBの中で
(1) Connection作成
(2) Connectionオープン
(3) 処理
(4) Connectionクローズ
(5) Dispose
とするのが良いと思います。

引用返信 編集キー/
■69785 / inTopicNo.3)  Re[2]: DB接続 どこでSqlConnectionをdispose
□投稿者/ ブルー (7回)-(2014/01/29(Wed) 16:17:21)
shu さん

お忙しい中ご回答頂きありがとうございます。

>InsertDBの中で
>(1) Connection作成
>(2) Connectionオープン
>(3) 処理
>(4) Connectionクローズ
>(5) Dispose

やはりInsertDBの中でオープン・クローズしてあげるしかないのですね。
接続は接続でまとめられたメソッドを利用できれば便利だと思いましたが、難しそうですね。

Connectionはフォームが閉じられた時に、自動でDisposeされるものなのでしょうか?
もしされるのであれば、Close、Disposeせずに、そのままにしておこうと思ったのですがセキュリティ上マズいでしょうか?
もしくは、使わないのに、オープンにしっぱなしだと何らかの不具合がでますでしょうか?


No69781 (shu さん) に返信
> ■No69780 (ブルー さん) に返信
>
> DBクラスのインスタンス作成では
> 接続情報だけ保存するようにして
>
> InsertDBの中で
> (1) Connection作成
> (2) Connectionオープン
> (3) 処理
> (4) Connectionクローズ
> (5) Dispose
> とするのが良いと思います。
>
引用返信 編集キー/
■69786 / inTopicNo.4)  Re[3]: DB接続 どこでSqlConnectionをdispose
□投稿者/ shu (476回)-(2014/01/29(Wed) 16:42:50)
No69785 (ブルー さん) に返信
> Connectionはフォームが閉じられた時に、自動でDisposeされるものなのでしょうか?
> もしされるのであれば、Close、Disposeせずに、そのままにしておこうと思ったのですがセキュリティ上マズいでしょうか?
> もしくは、使わないのに、オープンにしっぱなしだと何らかの不具合がでますでしょうか?
>
サーバー側に接続状態が残ってしまい、複数クライアントからの接続に支障をきたす場合があります。
引用返信 編集キー/
■69788 / inTopicNo.5)  Re[1]: DB接続 どこでSqlConnectionをdispose
□投稿者/ an (25回)-(2014/01/29(Wed) 16:47:34)
No69780 (ブルー さん) に返信
> この時、どこで、どうやってSqlCoonectionをdisposeしてやればいいかわかりません。お教え頂けませんでしょうか?

DBクラスに接続用メソッドがあるので、
切断用メソッドを作って、そこでSqlCoonectionをdispose呼び出してあげればいいのでは?

InsertDBメソッドを呼ぶ前に、接続用メソッドを呼ぶ必要があるので、
それと合わせて、InsertDBメソッドを呼び出した後は、忘れずに切断用メソッドを呼ぶようにする。

さらにいうと、例外発生時も考慮して、
DBクラスにIDisposableインターフェースを実装し、
DBクラスのDisposeメソッドにて、
SqlCoonectionなりDisposeが必要なものに対してDisposeしてあげて、
MainForm等から呼び出す場合に

try{
    using (db = new DB()){
        ConnectionDB();
        BeginTransDB();
        InsertDB();
        UpdateDB();
        DeleteDB();
        CommitDB();
        CloseDB();
    }
} catch(SqlConnection ex){
    sqlConn.Close();
    MessageBox.Show("接続失敗");
}

のような感じで使うとか?

試していないので、本当にできるか?考え方として合っているか?とか分かりませんので、
参考まで・・・。

引用返信 編集キー/
■69789 / inTopicNo.6)  Re[3]: DB接続 どこでSqlConnectionをdispose
□投稿者/ WebSurfer (168回)-(2014/01/29(Wed) 16:50:26)
No69785 (ブルー さん) に返信
> Connectionはフォームが閉じられた時に、自動でDisposeされるものなのでしょうか?
> もしされるのであれば、Close、Disposeせずに、そのままにしておこうと思ったのですがセキュリティ上マズいでしょうか?
> もしくは、使わないのに、オープンにしっぱなしだと何らかの不具合がでますでしょうか?

コネクションリークを防止するための基本について、まず以下のページを
読まれることをお勧めします。

.NETの例外処理 Part.2
http://blogs.msdn.com/b/nakama/archive/2009/01/02/net-part-2.aspx


今回の InsertDB メソッドの実装については、上記のページの[テーブル
アダプタを使う場合]のセクションにある最初のコードのように、Open し
ているか否かを調べて Open/Close の処置を行うようにしてはいかがですか?

Visual Studio の TableAdapter 構成ウィザードを利用して作る TableAdapter
クラスを使えば、自分では一行もコードを書かないで必要な実装ができるの
ではないかと思います。そちらも検討してみることをお勧めします。

自分で実装したいと言うことであっても、自動生成された TableAdapter の
コードはかなり参考になると思います。

Visual Studio の TableAdapter 構成ウィザードを起動して、「生成するメソ
ッドの選択」メニューで「更新を直接データベースに送信するためのメソッド
を生成する (GenereateDBDirectMethods) (U)」にチェックを入れて Insert,
Update, Delete メソッドを自動生成させて、そのコードを見てみてください。
引用返信 編集キー/
■69797 / inTopicNo.7)  Re[4]: DB接続 どこでSqlConnectionをdispose
□投稿者/ ブルー (8回)-(2014/01/30(Thu) 10:56:10)
shuさん

サーバー側に変な情報が残ってしまうのですか。勉強になります、ありがとうございます。

anさん

お教え頂きましたように、切断メソッドを作って対応してみました。ありがとうございます。
//=======================================================
//接続用クラス

class DB{

//DB接続文字列用変数
string conStr;

//接続変数
sqlConnection sqlConn;

public void ConnectionDB(){

conStr = "接続文字列";
sqlConn = new SqlConnection(conStr);

try{
sqlCon.Open();
} catch(SqlConnection ex){
sqlConn.Close();
MessageBox.Show("接続失敗");
}
}

//データベースにインサート
public void InsertDB(){
//Insertの処理 ここでsqlConnを利用する
}

//Insert処理

//切断処理
CloseDB();
}

//データベース切断
private void CloseDB()
{
sqlConn.Dispose();
}

WebSurfer さん

お教え頂きましたサイトを見てみました。大変勉強になってわかりやすかったです。ありがとうございます。

また自動生成されたTableAdapterのコードは見たことが無かったので、こちらも勉強になります。

皆様ありがとうございました。
解決済み
引用返信 編集キー/
■69799 / inTopicNo.8)  Re[5]: DB接続 どこでSqlConnectionをdispose
□投稿者/ WebSurfer (169回)-(2014/01/30(Thu) 11:30:20)
No69797 (ブルー さん) に返信
> WebSurfer さん
>
> お教え頂きましたサイトを見てみました。大変勉強になってわかりやすかったです。ありがとうございます。
>
> また自動生成されたTableAdapterのコードは見たことが無かったので、こちらも勉強になります。

ホントに見てますか? 見てたら上のレスに書いてあるような実装にはしないと思いますけど。
解決済み
引用返信 編集キー/
■69801 / inTopicNo.9)  Re[5]: DB接続 どこでSqlConnectionをdispose
□投稿者/ an (26回)-(2014/01/30(Thu) 11:57:57)
No69797 (ブルー さん) に返信
> anさん
>
> お教え頂きましたように、切断メソッドを作って対応してみました。ありがとうございます。
> //=======================================================
> //接続用クラス
>
> class DB{
>
> //DB接続文字列用変数
> string conStr;
>
> //接続変数
> sqlConnection sqlConn;
>
> public void ConnectionDB(){
>
> conStr = "接続文字列";
> sqlConn = new SqlConnection(conStr);
>
> try{
> sqlCon.Open();
> } catch(SqlConnection ex){
> sqlConn.Close();
> MessageBox.Show("接続失敗");
> }
> }
>
> //データベースにインサート
> public void InsertDB(){
> //Insertの処理 ここでsqlConnを利用する
> }
>
> //Insert処理
>
> //切断処理
> CloseDB();
> }
>
> //データベース切断
> private void CloseDB()
> {
> sqlConn.Dispose();
> }

なんか、正しく伝わっていないような気がしますので、補足します。
(というかミスリードしてしまったような?)

自分の説明した部分の肝は

>>DBクラスにIDisposableインターフェースを実装し、
>>DBクラスのDisposeメソッドにて、
>>SqlCoonectionなりDisposeが必要なものに対してDisposeしてあげて、

これだったのですが、上記ソースコードだと、
結局例外発生時等にDisposeされないような気がします。


そもそも、上記ソースコードをコピペしましたが、コンパイルエラーがあり、
動作しません。
なので、なんとなく修正してみました。
(「public void InsertDB」の位置、例外の型、細かい誤字等)
しかし、修正した上でのソースコードを眺めると違和感があります。

ConnectionDBメソッドの中でインサート処理するのでしょうか?
メソッド名(ConnectionDB)と実際の処理(接続&インサート&切断?)が
一致していないと思います・・・
(なんとなく修正した方法が間違っているのかな?
 でも、登場クラスも接続用クラスのみでメインクラスがいませんし・・・。)

そもそも、この方式でやるなら、Usingでいけそうな気が・・・。


本当に上記ソースコードでなのですか?

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -