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

わんくま同盟

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

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

ツリー一括表示

フィールド名の値について /ピカチュウ (17/11/13(Mon) 23:13) #85669
Re[1]: フィールド名の値について /しま (17/11/14(Tue) 00:09) #85670
Re[1]: フィールド名の値について /WebSurfer (17/11/14(Tue) 09:57) #85673


親記事 / ▼[ 85670 ] ▼[ 85673 ]
■85669 / 親階層)  フィールド名の値について
□投稿者/ ピカチュウ (1回)-(2017/11/13(Mon) 23:13:24)

分類:[C#] 

C# VS2017 Windows7

入力した情報をDBを通して登録(Insert)するコードを作っています。

本題ですが、初めのloadイベント(確認)はコネクションの情報(接続文字列)が反映されています。
次はボタンイベント(登録)では、接続文字列の情報が反映されていませんでした。

切断するときにDisposeしたので初期化されたので当然ですが、初期化されても、ボタンイベントはloadイベントも同じフィールド名から値を格納しているのかなと思いました。
フィールドの宣言で、一度しか情報が反映されないのでしょうか?

接続文字列はインスタンス共通なので、staticにしました
usingにすれば簡単に解決できるが、接続と切断のメソッドを分けているのは、form1のInsertループがあるので、何回も接続・切断ではサーバーが負担になるので避けています。
また、切断はClose()のみにすれば接続文字列は保持したまま通りますが、Disposeしないと問題はありますか?
登録する時間はバラバラですが、1分間に何回も登録連続したり、間をおいて(10分ぐらい?)、1分間に何回も登録、繰り返しの流れです。

SQL_ClassはSQL用と接続文字列などのDB関係をまとめて書き込んでいます。
ほかのクラスでは書き込んではいないです。

どうすれば、インスタンス共通で、loadイベントとボタンイベントでconnectionの値を反映するのでしょうか?
ご教示の程よろしくお願いします。

class SQL_Class
{
  //接続文字列情報 
private static OracleConnection connection = new OracleConnection(GetConnection());

  //DB接続
public static bool isDB_Open()
{
try
{
if(connection.State == ConnectionState.Closed)
{
connection.Open();
}
return true;
}
catch(Exception ex)
{
DB_Close();
return false;
}
}

//DB切断
public static void DB_Close()
{
try
{
connection.Close();
connection.Dispose();
}
catch(Exception ex)
{

}
}
}


//form1
private void Form1_Load(opject sender, EventArgs e)
{ 
    //接続確認
if(SQL_Class.isDB_Open())
{
this.lableMessage.Text = "接続は成功しました"
    }
else
{
this.lableMessage.Text = "接続は失敗しました"
    }

    //切断
SQL_Class.DB_Close();
}

//ボタン
private void Form1_button1(opject sender, EventArgs e)
{
//接続
if(SQL_Class.isDB_Open() == false)
{
this.lableMessage.Text = "接続は失敗しました"
return;
    }
    
    //いろいろな処理
//ここでループしながらDBで追加(Insert)している

    //切断
    SQL_Class.DB_Close(); 
  }
[ □ Tree ] 返信 編集キー/

▲[ 85669 ] / 返信無し
■85670 / 1階層)  Re[1]: フィールド名の値について
□投稿者/ しま (2回)-(2017/11/14(Tue) 00:09:03)
No85669 (ピカチュウ さん) に返信
> C# VS2017 Windows7
>
> 入力した情報をDBを通して登録(Insert)するコードを作っています。
>
> 本題ですが、初めのloadイベント(確認)はコネクションの情報(接続文字列)が反映されています。
> 次はボタンイベント(登録)では、接続文字列の情報が反映されていませんでした。
>

設計がよろしくありません(あなたが使いたい様な動きが出来るように設計できていないという意味です)

static な SQL_Class.connection が SQL_Clas.Close() で Dispose(); してしまうのでは SQL_Class の本体である SQL_Class.connection オブジェクトは生きている
のに、SQL_Class.connection が保持しているDBとの接続はいなくなっている状態を作り出していて上手く扱えなくなっているところが問題のようですが、
この SQL_Class.connetion を Dispose() するメソッドを別途追加して本当に不要になったときに SQL_Class.connection.Dispose(); が実行できれば良いだけ
かもしれません

そもそも SQL_Class を static なメンバーだけで構成する設計がよろしいかどうかも検討してみてください
(いいとか悪いとかは言っていません、違う設計もあるでしょうということです)
connection がある状態と(new した後から Dispose(); するまでの間)ない状態と(Dispose(); した後)が存在するのだから
オブジェクト(=クラスのインスタンス)を生成した方が判りやすいかも知れません
そして、インスタンスを Dispose() するときに connection を Dispose() するということも出来るのではないでしょうか?

あと、ソースコードにインデントがないので見づらいことにお気付きですか?
次回からソースコードを含む場合は、投稿モードを"図表モード"で投稿してください

[ 親 85669 / □ Tree ] 返信 編集キー/

▲[ 85669 ] / 返信無し
■85673 / 1階層)  Re[1]: フィールド名の値について
□投稿者/ WebSurfer (1342回)-(2017/11/14(Tue) 09:57:41)
No85669 (ピカチュウ さん) に返信

何を作っているかと、DB のことを質問しているのですからその DB とプロバイダは何か
とそのバージョンぐらいは書きましょう。

コードを読めばわかるとは言わないでくださいね。質問者さんが最初に一行書けばすむ
ことなのですから。

書けば、興味のある人は深く読んでくれるかもしれませんし、興味の無い人には時間の
節約になります。

・・・と注文を付けるばかりでは何ですので、

> 何回も接続・切断ではサーバーが負担になるので避けています。

プロバイダに ODP.NET を使っているとすると接続プールが利用できると思います。その
場合、Open / Close は接続プールからの接続の借り出し / 返却となります。

接続プールを使っていれば、使う直前に Open して、使い終わったら即 Close して問題
ない・・・と言うか、そういう使い方が基本になるはずです。

> 切断はClose()のみにすれば接続文字列は保持したまま通りますが、Disposeしないと問題はありますか?

Connection の Dispose は Close と同じです。

なので、using 句等を使って、使い終わったら、コネクションリークの問題を避けるため
にも、即&必ず Dispose するべきだと思います。


そのあたりのことは、SQL Server + SqlClient の話ですが、以下の記事(特に Part 2)
が参考になると思いますので一読してみてください。

.NETの例外処理 Part.1
https://blogs.msdn.microsoft.com/nakama/2008/12/29/net-part-1/

.NETの例外処理 Part.2
https://blogs.msdn.microsoft.com/nakama/2009/01/02/net-part-2/
[ 親 85669 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -