- PR -

クラスを使用する際のコネクションの閉じ方

投稿者投稿内容
モンジ
ベテラン
会議室デビュー日: 2005/09/06
投稿数: 85
投稿日時: 2006-08-21 17:32
いつもお世話になっています。

クラスを使って、SQLの戻り値をDataReaderに格納していますが、
クラス内でオープンしたコネクションをどこで閉じればよいか悩んでおります。

開発環境:VB.net 2003、ADO.net。Windowsアプリケーション。DBはOracle。

言葉では説明しづらいので、コードをUPさせていただきます。
下記のコーディングですと、クラス内でFinallyを使ってコネクションを閉じると、
Form側に戻ったときにエラーになってしまいます。
どなたかご教授お願いいたします。

コード:
Form側

strSQL = _
"SQL文"

Dim DRC as New clsDR
DR = DRC.Get_DR(strSQL)



コード:
Class側(clsDR)

Function Get_DR(Byval x as string) as OracleDataReader

Dim oCn As New OracleConnection
Dim oCmd As New OracleCommand

oCn.ConnectionString = "接続文字列"
oCn.Open()

 'コネクションの設定
oCmd.Connection = oCn
oCmd.CommandText = x

Return oCmd.ExecuteReader





R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-08-21 17:52
この書き方は、OracleDataReader オブジェクトを提供するメソッド内で接続してますね。
クラス単位で接続、切断するほうがわかりやすいんじゃないでしょうか?

で、Dispose() メソッドや Close()メソッドを実装するなどで、そこでコネクションを閉じるとか
Kazuki
ぬし
会議室デビュー日: 2004/10/13
投稿数: 298
投稿日時: 2006-08-21 18:08
DataReaderは接続型なので、コネクションを開いて閉じるタイミングは
DataReaderを取得する前から使用終了までです。

メソッド内でコネクションを開いて閉じたい場合は、DataSetにデータを詰めるか
データを格納するための独自の型のクラスに詰め込んでReturnしないといけません。

<以下追記>
この場合なら、外部から開いたコネクションを貰うような形にするのがいいのかな
C#になりますが、こんなイメージ(動く保障無いです)
コード:

public class DR {
private OracleConnection conn;
public DR(Connection conn) {
this.conn = conn;
}
public DataReader GetDR(string sql) {
OracleCommand command = new ....();
// commandに色々設定
return command.ExecuteReader();
}
}

使う側
using(OracleConnection conn = new OracleConnection()) {
// connにごにょごにょ設定する
conn.Open(); // 開く
DR dr = new DR(conn);
OracleDataReader r = dr.GetDR("select ....");
// rをごにょごにょする
conn.Close(); // 閉じる
}




[ メッセージ編集済み 編集者: Kazuki 編集日時 2006-08-21 18:16 ]
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-08-21 18:50
開いたスコープと同じスコープで閉じるのが解りやすくて良いと思います。

Open, Close を外に出したくないのなら、
Kazuki さんのおっしゃられているように
DataSet や HashTable, 独自のClass なんかに格納して返してあげればいいかな。
モンジ
ベテラン
会議室デビュー日: 2005/09/06
投稿数: 85
投稿日時: 2006-08-29 11:53
大変レスが遅くなりまして、申し訳ありません。
Kazukiさんの方法(DB接続のクラスを用意して呼び出し側でDB接続・切断)
しようと思いますが、呼び出し側の下記コードが分かりませんでした。
(C#なので…。コネクションをクラスに渡している?)

DR dr = new DR(conn);

VBでどのように書けばよいか、どなたかご教授くださいませ。
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-08-29 12:00
引用:

モンジさんの書き込み (2006-08-29 11:53) より:
(C#なので…。コネクションをクラスに渡している?)


理解できてなさそう。
C#なのでの意味がわからないし。
コネクションをクラスに渡しているわけじゃないし。
クラスに渡すって変だし・・

>DR dr = new DR(conn);
>VBでどのように書けばよいか、どなたかご教授くださいませ。
VBに書き直すのは簡単だけど上に書いたことが理解できなければ意味がないよ。違うかね?
モンジ
ベテラン
会議室デビュー日: 2005/09/06
投稿数: 85
投稿日時: 2006-09-04 18:12
ぶさいくろうさん、レスありがとうございます。
C#だからって、コードを解析するのに腰が引けておりました。
大変失礼しました。

自分でVB.NETに書き直してみました。
下記コードに書き換えたところ、接続のOpen、Closeとも、
呼び出し側から記述することができました。

誠にもしわけありませんが、
間違って理解しているようでしたら、
ご指摘お願いします。

コード:
クラス側

Public Class clsDR

    'メンバ変数
    Private O_cn As OracleConnection

    'コンストラクタ
    Public Sub New(ByVal Ocn As OracleConnection)
        O_cn = Ocn
    End Sub

    Function GetDR(ByVal x As String) As OracleDataReader

        Dim oCmd As New OracleCommand
        oCmd.Connection = O_cn

        oCmd.CommandText = x

        Return oCmd.ExecuteReader

    End Function

呼び出し側
    Dim DR As OracleDataReader

        Dim oCn As New OracleConnection
        oCn.ConnectionString = "接続文字列"
        oCn.Open()

        Dim strSQL As String = _
        "SQL文"

    'クラスのインスタンス化(コンストラクタの引数にコネクション指定)
        Dim DRC As New clsDR(oCn)
        DR = DRC.GetDR(strSQL)
    
    While DR.Read
        (続く)

 oCn.Close



かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-09-04 19:13
なんとなくこれだとクラスを別に作る必要がないようにも思える。

引用:

モンジさんの書き込み (2006-09-04 18:12) より:
コード:
    'クラスのインスタンス化(コンストラクタの引数にコネクション指定)
        Dim DRC As New clsDR(oCn)
        DR = DRC.GetDR(strSQL)




の部分って
コード:
        Dim cmd As New OracleCommand(strSQL, oCn)
        DR = cmd.ExecuteReader()


と同じこと?

スキルアップ/キャリアアップ(JOB@IT)