- PR -

DataAdapter.Fill時の接続エラー

1
投稿者投稿内容
Chikota
常連さん
会議室デビュー日: 2005/09/08
投稿数: 23
投稿日時: 2006-02-21 17:26
VB.NET2003でwindowsフォームを作成しています。

Ole接続によりAccessに接続していて、画面をリフレッシュするのに以下のコードを実行するとエラーになってしまいます。
Accessの参照テーブルは二つあり、注文と注文明細のような親子関係にあります。

コード:
Private Sub FillData()
    dsDataset.Clear
    daOrder.Fill(dsDataset,"Order")
    daOrderDetail.Fill(dsDataset,"OrderDetail")
End Sub



4行目の実行で以下のエラーが起きます。
「この接続に関連付けられているDataReaderが既に開いています。このDataReaderを最初に閉じる必要があります。」

daOrderとdaOrderDetailは同じOleDataConnectionを利用しています。
また、毎回エラーとなるわけではなく、フォームを開くとき(Form_Load)にデータを読み込む時にはエラーになりません。

上記のエラーは実行しようとしたコマンドが使用しようとしているコネクションを利用したDataReaderが閉じていないときに起こるものと理解しているのですが、このコード上ではエラーを起こす直前に、同じコネクションを使ったDataAdapterが問題なく実行できている(3行目)ので、対処方法がわからず困ってしまいました。

どなたかアドバイスをいただけないでしょうか。

よろしくお願いいたします。
burton999
ぬし
会議室デビュー日: 2003/10/06
投稿数: 898
お住まい・勤務地: 東京
投稿日時: 2006-02-21 17:33
本当に4行目でエラーなのでしょうか?
とりあえず原因はDataReaderなので、閉じましょう。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-02-21 17:54
引用:

burton999さんの書き込み (2006-02-21 17:33) より:

本当に4行目でエラーなのでしょうか?


私も違うと思いますね。

IDE で実行していると稀に違う場所でブレークすることがあります。
非同期系だったら当たり前のことなんですが。

# この場合は「緑色」でインライン表示されるんだったかな。

引用:

とりあえず原因はDataReaderなので、閉じましょう。


そうですね。

ソースコード中にない DataReader の Close 漏れが原因です。
ソースコードにあるのは DataAdapter だけなので、どこなのかはわかりませんが。
で、こういう漏れが発生しないためにも、Try 〜 Finally で実装しておきましょう。

  オブジェクトの破棄を保証する

それと、なるべくアクセス修飾子は短くしておきましょう。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Chikota
常連さん
会議室デビュー日: 2005/09/08
投稿数: 23
投稿日時: 2006-02-21 22:19
DataReaderをどこかで閉じ忘れがないかは確認済みだったのですが、もう一度調べてみましたが、すべて処理していました。

本当に4行目なのかとのアドバイスをいただいたので、調べたところエラー発生の場所が違うことがわかりました。
OrderDetailテーブルにバインドしたCurrencyManagerがあり、PositionChangedイベントを使用しています。その派生効果で発生するイベントの中にDBに接続するDataAdapterがありました。
なぜかこのPositionChangedイベントは、ステップインのデバックでスルーしてしまうので見逃してしまっていました。

1.daOrderDetailがデータテーブルの読み込みを開始。
2.読み込み途中でCurrencyManagerのPositionChangedイベント発生
3.デリゲート先でComboBoxのSelectionIndexを変更
4.ComboBoxのイベント発生
5.デリゲート先でDataAdapterからデータの取得しようとする ⇒ エラー

となっているようです。

前回のコードを以下のように修正することで、無事に読み込むことができるようになりました。

コード:
Private Sub FillData()
    '// イベント発生を解除
    RemoveHandler cmDetail.PositionChanged, AddressOf Me.cmDetail_PositionChanged

    dsDataset.Clear
    daOrder.Fill(dsDataset,"Order")
    daOrderDetail.Fill(dsDataset,"OrderDetail")

    '// イベントを設定
    AddHandler cmDetail.PositionChanged, AddressOf Me.cmDetail_PositionChanged
End Sub



いろいろと勉強になりました。
ありがとうございました。
1

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