.NET アプリケーションでの ADODB.dll 利用から ADO.NET への移行のススメ

Last Update:
このエントリーをはてなブックマークに追加

こんにちは、Japan Developer Support Core チームの高橋です。データアクセス テクノロジーの移行のススメもこれで第 4 弾、今回は .NET Framework や .NET の開発アプリケーションにおいて、データベースアクセスに ADODB.dllInterop.ADODB.dll を使用されているケースを取り上げます。

今でも時々このようなアプリケーションに関するお問い合わせを見かけることがあり、「動いているから問題ない」と考えていらっしゃる方も多いかもしれませんが、.NET Framework がリリースされてから二十数年でまだこれを使用しているというのは少々想定外なんです。

そこで、本記事では、ADODB.dll の正体とそのサポート状況、そして ADO.NET への移行が必要な理由について解説します。

ADODB.dll とは何か

ADO (ActiveX Data Objects) について

まず、ADO について簡単におさらいしましょう。ADO は、VB6.0 や VC++ などの非マネージコード向けのデータアクセステクノロジーです。Windows に同梱される Windows DAC (Windows Data Access Components、旧 Microsoft Data Access Components = MDAC) で提供され、COM (Component Object Model) ベースで動作します。

参考: Microsoft SQL Server のドライバー履歴

ADODB.dll の正体

ADODB.dll は、この COM ベースの ADO を .NET Framework アプリケーションで使用できるようにしたラッパーです。正式には「プライマリ相互運用機能アセンブリ (Primary Interop Assembly、略して PIA)」と呼ばれます。

この PIA は ADO を使用する VB6 アプリケーションを .NET Framework に移行する際の互換性を提供する目的で作られました。またこのように主にデータ アクセス機能を含む開発で使用されることから、Visual Studio や SQL Server Management Studio、Office とともに提供されており、以前のバージョンではインストール時に GAC (Global Assembly Cache) にも配置されていました。しかし昨今は .NET Framework がリリースされてから 20 年以上が経過していることもあり、製品による提供を終了、もしくは、GAC には配置せずに製品フォルダにのみ配置されるよう変更されています。
このように Windows OS の GAC 上に必ずしも存在するアセンブリではない点、留意が必要です。

次に、Visual Studio にて VB.NET や C# などのプロジェクトを作成し、COM 参照として「Microsoft ActiveX Data Objects」を追加した場合には Interop.ADODB.dll が生成されますが、このアセンブリも同様の ADO のラッパーです。こちらは「相互運用機能アセンブリ (Interop Assembly、略して IA)」と呼ばれます。タイプライブラリ インポーター (tlbimp.exe) を使用して同様に「Microsoft ActiveX Data Objects」をもとに生成されたアセンブリも IA です。

重要:.NET での ADODB.dll 利用はサポート対象外

ここが最も重要なポイントです。

.NET Framework および .NET 上での ADODB.dll などの ADO ラッパーはマイクロソフトのサポート対象外です。

マイクロソフトの公式ドキュメントには、以下のように明記されています:

Caution: ADO and ADO MD have not been fully tested in a Microsoft .NET Framework environment. They may cause intermittent issues, especially in service-based applications or in multithreaded applications. The techniques that are discussed in this article should only be used as a temporary measure during migration to ADO.NET. You should only use these techniques after you have conducted complete testing to make sure that there are no compatibility issues. Any issues that are caused by using ADO or ADO MD in this manner are unsupported.

出典: ADO application issues on Windows 7 SP1 or Windows Server 2008 R2 SP1

つまり、ADODB.dll や Interop.ADODB.dll は、ADO.NET への移行を前提とした一時的な措置として提供されているに過ぎません。COM Interop を経由するため完全にテストされておらず、問題が発生してもその原因を特定して修正するなどのサポートは受けられないのです。

なお、アンマネージのアプリケーション(VC++ など)からの ADO の利用は引き続きサポート対象です。サポート対象外となるのは、.NET Framework / .NET のアプリケーション内での ADODB.dll などの ADO のラッパーです。

参考: Microsoft SQL Server のドライバー履歴

利用し続けた場合のリスク

「現在動いているから大丈夫」と思われるかもしれませんが、以下のようなリスクがあります:

  • 環境移行時のトラブル
    ADODB.dll を使用するアプリケーションを別の環境に移行した際、ADODB.dll が見つからないという問題が発生することがあります。ADODB.dll は Visual Studio や Office とともに提供されるため、移行先の OS にはインストールされていない可能性があります。しかも、ADODB.dll は再頒布が許可されていません。そのため PIA を使用していたケースでは、代わりに IA を使うようそのアプリケーションのプロジェクトにおける参照設定を変更する必要があります。
  • マルチスレッド環境での互換性問題
    前述の「.NET Framework 上での ADO や ADO MD がサポート対象外である」ことを示したドキュメントにもあるように、サービスベースのマルチスレッドアプリケーションで互換性の問題が発生する可能性があり、過去に報告例があります。
  • 将来的な機能強化が期待できない
    .NET Framework/.NET の ADO.NET (データプロバイダー含む) であれば機能強化が期待できるのに対して、ADO はレガシーテクノロジーにつき、新機能の追加などの機能強化が行われる見込みは低いです。
  • サポート対象外
    何か問題が発生しても、ADODB.dll に起因する問題については、マイクロソフトのサポートを受けることができません。

移行の進め方

.NET Framework および .NET には、ADO.NET という専用のマネージドデータアクセステクノロジーが用意されています。ADO の PIA (ADODB.dll) もしくは IA (Interop.ADODB.dll など) を使用している場合は、ADO.NET への移行を強く推奨します。

接続先 RDBMS によるデータプロバイダーの決定

ADO.NET への移行にあたり重要となりますのは、アクセス先のデータベース (RDBMS) の種類です。

ADO を使用するアプリケーションでは、RDBMS へのアクセスにはその RDBMS 提供元などからその RDBMS に対応する OLE DB プロバイダーが提供されており、必要に応じてそのインストールを行った上で、接続文字列における Provider キーワードに使用する OLE DB プロバイダー名を指定しているはずです。

ADO.NET に移行する場合には、まずは使用している RDBMS の提供元から専用の .NET Framework データプロバイダーが提供されているかどうかを確認しましょう。たとえばマイクロソフト製品の SQL Server や Azure SQL Database を使用する場合には、以下のプロバイダーを使用できます。

データソース ADO.NET プロバイダー 名前空間
SQL Server
Azure SQL
Microsoft .NET Framework Data Provider for SQL Server System.Data.SqlClient (.NET Framework/.NET Core/.NET 5+)
SQL Server
Azure SQL
Microsoft SqlClient Data Provider for SQL Server Microsoft.Data.SqlClient (.NET Framework/NET Core/.NET 5+) (推奨)

一例ですが、ADODB を使用した SQL Server への接続処理は ADO.NET では次のように変更できます。(主に VB6.0 から VB.NET へ移行する際に ADODB を使用しているケースが多いため VB.NET のコード例を紹介します。)

// ADODB を使用した SQL Server への接続

1
2
3
4
5
6
7
Imports ADODB
...

Dim connectionString As String = "Provider=MSOLEDBSQL;Data Source=yourSQL;Initial Catalog=yourDB;Integrated Security=SSPI;"
Dim con As New Connection()
con.connectionString = connectionString
con.Open()

// ADO.NET + Microsoft.Data.SqlClient を使用した SQL Server への接続

1
2
3
4
5
6
7
Imports Microsoft.Data.SqlClient
...

Dim connectionString As String = "Data Source=yourSQL;Initial Catalog=yourDB;Integrated Security=SSPI;"
Dim con As New SqlConnection()
con.connectionString = connectionString
con.Open()

また移行のススメ第 3 弾の Oracle 向けデータプロバイダー移行のススメ に記載の通り、Oracle へのアクセスにおいては Oracle 社提供の専用のデータプロバイダーを使用することもできます。

このような専用のデータプロバイダーが提供されていない場合にも ADO.NET の利用は可能です。具体的には、ADO で使用していた OLE DB プロバイダーを引き続き使用することができます。もしくは、ODBC ドライバーを使用することも可能です。その際に使用できるのが、以下のデータプロバイダーです。

データソース ADO.NET プロバイダー 名前空間
OLE DB データソース Microsoft .NET Framework Data Provider for OLE DB System.Data.OleDb
ODBC データソース Microsoft .NET Framework Data Provider for ODBC System.Data.Odbc

例えば移行のススメ第 1 弾の Jet データベースエンジンの移行のススメ に記載した移行先候補の Access ランタイムを使用する場合には、専用のマネージドのデータプロバイダーの提供はないため、次のように引き続き接続文字列に同じ OLE DB プロバイダーを指定してアクセスするよう実装できます。

1
2
3
4
5
6
7
Imports System.Data.OleDb
...

Dim connectionString As String = "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=C:\path\to\your\database.accdb;User ID=yourusername;Password=yourpassword;"
Dim con As New OleDbConnection()
con.connectionString = connectionString
con.Open()

ADO と ADO.NET の実装差異の把握

参考までに、ADO で提供されるクラスの ADO.NET での対応関係を以下の通り示します。

ADO (ADODB) ADO.NET (xx.Data.SqlClient の例) ADO.NET (System.Data.OleDb の例)
ADODB.Connection SqlConnection OleDbConnection
ADODB.Command SqlCommand OleDbCommand
ADODB.Recordset (接続型) SqlDataReader OleDbDataReader
ADODB.Recordset (非接続型) DataSet / DataTable DataSet / DataTable
ADODB.Parameter SqlParameter OleDbParameter

接続に関しては前述のコード例のように、使用する名前空間・クラス・接続文字列が主な変更点となります。

一方で、ADO.NET における SQL 文の実行やデータの処理に関しては、単にクラスやメソッドを変更するのみではなく、設計の観点で考慮するとよい点があります。以下に補足します。

  • 接続型/非接続型
    ADO.NET では、ADO では主流であった接続型よりも非接続型が主流となっています。具体的には、SQL 文を実行して得られたデータは Recordset を介して処理ができますが、この Recordset をクライアント カーソル (adUseClient) としてデータ取得した後、紐づく ActiveConnectionNothing に設定する方法が非接続型です。>> レコードセットの切断と再接続
    このような手法を取っている ADO アプリケーションはあまり見ることはありませんが、ADO.NET ではこれと同等の DataSetDataTable を使用する方法は ADO の非接続型の利用に比べて一般的です。これは長時間放置される可能性のある Web アプリケーション利用における特徴や、クライアントマシン性能向上が主な理由です。

  • カーソル
    ADO では様々なサーバー カーソルを使用できましたが、ADO.NET における DbDataReader による接続型の処理では「前方スクロール+読み取り専用」のカーソルのみ使用可能です。つまり、引き続きサーバー カーソルを用いた読み取り操作は可能ですが、他の種類のカーソルを API カーソル (キーセット ドリブン カーソル、動的カーソル、静的カーソル) にて実現することはできません。

  • データの変更
    ADO.NET においてはサーバー カーソルは読み取り専用のみとなりますので、カーソル位置指定更新はできません。
    変更操作に関しては以下のいずれかにて対応します。

    • ADO における 非接続型 RecordsetUpdateBatch メソッドと同様に DataSetDataTable を使用して変更操作を一括で反映する方法。(DataTable 内のレコードに対して実行された変更操作ごとに INSERT 文などの SQL 文が実行されます。)
    • ADO における Connection または Command オブジェクトの Execute メソッドによる SQL 文 (ストアドプロシージャ含む) 実行と同様に、DbCommand (及びその派生クラス) の ExecuteNonQuery メソッドなどを実行する方法。
  • オプティミスティック同時実行制御
    ADO による SQL 文実行においても adLockOptimistic というロック タイプで使用されるケースは多数ありますが、基本的に接続型で利用している限りは位置指定更新なども可能であったため、厳密なロック管理を必要としていない限りは、それほどこのオプティミスティック (楽観的) ロックを意識する必要がないケースもあります。しかし、ADO と ADO.NET のいずれにおいても非接続型とする場合は、接続を切断している間の RDBMS 側の変更を前提とした設計が必要となります。そのため、仮に ADO.NET に移行するにあたって変更操作を伴うデータ処理を非接続型にて行う場合には、オプティミスティック同時実行制御を念頭においた設計とする必要がある点にご留意ください。

ここで説明した ADO.NET での実装に関しては以下のページを参考にしてください。

ADO.NET への移行のメリット

ADO.NET の基本機能に関する継続的なメンテナンスと機能強化、最新の .NET バージョンにへの対応などが行われていますので、それを踏まえた正式なサポートが受けられます。

また後述しますが、RDBMS ごとのデータ プロバイダーに関してもその提供元にて RDBMS 自体の最新機能に対応するようバージョンアップおよびメンテナンスが行われています。たとえば SQL Server 向けのデータプロバイダーに関しては Always Encrypted、Microsoft Entra ID 認証など、SQL Server の最新機能を利用できます。

また、専用のデータプロバイダーが提供されているケースのメリットですが、アクセス経路上の余計なモジュールが不要になる点もあげられます。

  • ADODB 利用: ADODB → OLE DB → OLE DB Provider → Network → RDBMS
  • ADO.NET 利用: Microsoft.Data.SqlClient → Network → RDBMS

不要な処理が排除されることでわずかでもパフォーマンスにおける利点が得られること、ならびに、トラブルシューティングがシンプルになります。

まとめ:今すぐ移行計画を立てましょう

ADODB.dll や Interop.ADODB.dll などの ADO のラッパーである相互運用機能アセンブリを .NET Framework や .NET で使用しているアプリケーションは、「動いているから問題ない」という状態とはいえず、元来 ADO.NET への移行を踏まえて利用されることが想定であったこと、そのアセンブリ自体はサポート対象外であることを把握できましたでしょうか。将来的なリスクを抱えていると言えますので、すぐに ADO.NET への移行計画を立てることをお勧めします。

移行には時間がかかるかもしれませんが、アプリケーションの安定性と保守性を考えると、早めの対応が重要です。まずは現状のコードを確認し、ADODB の使用箇所を特定するところから始めてみてはいかがでしょうか。

ADO.NET についてご不明な点がございましたら、マイクロソフトのサポートチームまでお気軽にお問い合わせください。


本ブログの内容は弊社の公式見解として保証されるものではなく、開発・運用時の参考情報としてご活用いただくことを目的としています。もし公式な見解が必要な場合は、弊社ドキュメント (https://learn.microsoft.comhttps://support.microsoft.com) をご参照いただくか、もしくは私共サポートまでお問い合わせください。