大量にDbDataAdapter使うコードで、途中でFillできなくなって調べた結果です。
System.Data.Common.DbDataAdapterにはSystem.Data.IDbDataAdapterインターフェースの実装であるSelect/Insert/Update/DeleteCommandプロパティがあり、これらのプロパティにはSystem.Data.IDbCommand型のオブジェクトの設定/取得が可能です。
そして、DbDataAdapter.Disposeメソッドを呼び出しても、この4つのコマンドオブジェクトはDisposeされず、nullが設定されるだけです。したがって、各プロパティに設定したコマンドオブジェクトは、そのコマンドオブジェクトを生成する側で、明示的にDisposeしてやらないといけません。
override protected void Dispose(bool disposing) { // V1.0.3300, MDAC 69629 if (disposing) { // release mananged objects IDbDataAdapter pthis = (IDbDataAdapter) this; // must cast to interface to obtain correct value pthis.SelectCommand = null; pthis.InsertCommand = null; pthis.UpdateCommand = null; pthis.DeleteCommand = null; } // release unmanaged objects base.Dispose(disposing); // notify base classes }
最初、どうしてこうなってるのかなーと思ったのですが、DbDataAdapterはあくまでAdapterであって、Compositionではないからかと納得しました。どういうことかというと、DbDataAdapterへの各コマンドの付け外しは自由自在なので、DbDataAdapterがコマンドオブジェクトの死活管理を行うことはできないんですよね。
ハマりかけてなるほどなぁという話でした。