私は、レガシーVB6アプリ(データベースとしてMS Accessを使用します。質問しないでください)を.NETに段階的に移植するという任務を負っています。
これは長いものになるでしょうが、少し文脈を与える方が良いと思います。
このアプリには、アプリのフォルダーにあるDLLに基づいて動的に作成されるメニュー付きのメインMDIフォームがあります。これは基本的にプラグインのようなものです。各DLLはメニュー項目で表され、クリックするとDLLに含まれるメインフォームが開き、必要に応じて呼び出さSetParent()
れます。
MDIフォームが私の出発点です。上記のフォームを開くことができるように、それを十分に書き直したいと思います(もちろん、再設計と単体テストを行います)。それを釘付けにしたら、一度に1つのDLLの書き直しを開始します。
すべてのDLLにはADO接続が必要です。これは、C#から渡すことができました。
問題は、それらのプラグインの1つ(少なくとも、おそらく他の多くのプラグイン)がADOXを使用してデータベースで処理を実行することです。ここに問題があります。つまり、ADOX.CatalogのActiveConnectionプロパティをADO接続に設定しようとすると、すべて実行時エラー3001が表示されます:Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.
私は自分が間違っていることを一生理解することができません。
VB6コードは、可能な限り単純です。
Dim c As New ADOX.Catalog
Set c.ActiveConnection = theAdoConnectionComingFromDotNet ' error!
ADO接続を作成するC#コードは、VB接続と同じくらい簡単です。
var conn = new ADODB.Connection();
conn.Open("Provider=Microsoft.JET.Oledb;[...]");
そして、への呼び出しはOpen()
成功します。ActiveConnection
次のように、C#側でを設定しようとすると、次のようになります。
var catalog = new ADOX.Catalog();
catalog.ActiveConnection = conn;
すべてが機能します。
これで、C#側でADOXをインスタンス化してVB6に渡すだけで問題を回避できますが、VB6コード(もちろん単一の単体テストはありません)を微調整することでPITAになる可能性があり、私はそうではありません。そもそもそれは簡単です(アプリは一度に複数のAccess DBを使用でき、必要に応じてそれぞれへの接続を開いたり閉じたりできるため)。
だから、誰かが私が間違っていることについて何か考えを持っていますか?C#から、.NETタブとCOMタブの両方からADODBを参照しようとしました(そして、COMタブから選択したADOバージョンは正しいものです:2.5 ...繰り返しますが、尋ねないでください)が、それでも喜び。
編集
次のように、C#からの接続にRecordSetのActiveConnectionプロパティを割り当てようとすると、まったく同じことが起こります。
Dim rs As New ADODB.Recordset
Set rs.ActiveConnection = theAdoConnectionComingFromDotNet
ActiveConnectionはバリアントであるため、私が考えることができるもう1つの回避策は、接続のConnectionStringプロパティに設定することです。それは機能しますが、毎回新しい接続を作成して開くことになり、率直に言って私はそれが好きではありません。