Accessデータベースを.NETで追加すると「Failed to load Microsoft.Data.SqlClient」が出る原因とOleDb解決手順

Visual Studio で .NET(.NET 6/7/8 など)のプロジェクトに Access(.mdb/.accdb)を追加しようとすると、「Failed to load Microsoft.Data.SqlClient…」でデータソースが壊れることがあります。原因は SQL Server 用 SqlClient を前提にした構成。Access 用 OleDb への切り替えと 32/64bit 整合の手順を解説します。

目次

起きている現象:Access を追加した瞬間に SqlClient の読み込みエラーが出る

代表的な症状は次のようなものです。

  • データソースの追加(データベース追加)時に 「Failed to load Microsoft.Data.SqlClient version=5.0.0.0 …」 のようなメッセージが出る
  • Server Explorer / データソース ウィザード上でデータベースに 赤い× が付く
  • テーブルやカラムが展開できない/フォームにフィールドをドラッグできない
  • Access Database Engine(ACE)を入れても改善しない、NuGet に Microsoft.Data.SqlClient を追加しても改善しない

この状況は「Access 自体が壊れている」というより、プロジェクト(設計時の仕組みも含む)が “SQL Server 前提” の方向に寄ってしまい、Access を扱うのに不適切なデータプロバイダーを読みに行っていることが多いです。

結論:Microsoft.Data.SqlClient は SQL Server 用。Access は OleDb(ACE/Jet)で扱う

まず押さえるべきポイントはシンプルです。

  • Microsoft.Data.SqlClient は SQL Server 用 のデータプロバイダーです(名前のとおり “SqlClient”)。
  • Access(.mdb / .accdb)を扱う基本は OleDb(Jet/ACE) です。

そのため、Access をつなぎたいのに Microsoft.Data.SqlClient の読み込みエラーで詰まっている場合、根本的には「Access 用の経路」に SqlClient 依存が入り込んでいることが問題になります。ここを整理して OleDb に一本化すると、デザイナーが復活したり、少なくとも実行時の接続が安定します。

まずやること:どの“層”でエラーが出ているかを切り分ける

同じエラー文でも、発生箇所が違うと対処も変わります。最初に次のどれに近いかを確認してください。

どこで失敗している?よくある状況優先して見るポイント
Visual Studio のデータソース追加/デザイナー操作(設計時)赤い×、ドラッグ&ドロップ不可、ウィザードが落ちるプロジェクト参照・NuGet 依存、VS の設計時コンポーネント、SqlClient の混入
アプリ実行時(起動後の DB 接続)接続文字列で例外、プロバイダー未登録ACE のインストール、32/64bit 整合、接続文字列(Provider)

この記事は「設計時に SqlClient を読もうとしてこける」ケースを中心に、実行時の詰まりポイントも合わせて解説します。

最短で直す手順:Access 用に OleDb 構成へ寄せる

SqlClient を “Access 用の道” から外す

Access を扱う部分に Microsoft.Data.SqlClient が必要になる場面は基本的にありません。次の観点で整理します。

  • プロジェクトに Microsoft.Data.SqlClient を明示的に追加しているなら、Access だけが目的の場合は削除候補。
  • 他のライブラリが依存していて削除できない場合は、バージョンを揃える(統一する)ことが重要。
  • 複数プロジェクトのソリューションなら、参照が “どこかだけ古い” ことが原因になりやすい。

実際に「SqlClient のバージョン調整で解決した」という報告が多いのは、設計時に読み込まれる Microsoft.Data.SqlClient の期待バージョンと、手元に存在するバージョンがズレているケースがあるためです。Access を扱う目的なら、そもそも SqlClient を不要にするのが最も安全です。

System.Data.OleDb を参照する(.NET / .NET Core でも可)

.NET(.NET 5 以降 / .NET Core 系)で OleDb を使う場合、NuGet パッケージ参照が前提になることが多いです。プロジェクト(csproj)に次を追加します。

<ItemGroup>
  <PackageReference Include="System.Data.OleDb" Version="8.0.0" />
</ItemGroup>

ポイントは次のとおりです。

  • System.Data.OleDb は Windows 向けの機能です(Access 自体も Windows 前提になりやすい)。
  • UI デザイナーが完全復活するかは Visual Studio の機能差にも左右されますが、少なくとも “実行時に Access を扱うための土台” は整います。

接続文字列を Access(ACE)にする

Access の接続で最も多い落とし穴が、Provider の指定です。近年の環境では Jet よりも ACE(Access Database Engine)を使う場面が増えています。

ファイル形式推奨 Provider 例補足
.accdbProvider=Microsoft.ACE.OLEDB.16.0;環境により 12.0 の場合もあります(インストール状況に依存)。
.mdbProvider=Microsoft.ACE.OLEDB.16.0;古い .mdb でも ACE で開けることが多く、Jet 固定より詰まりにくいです。

.accdb を開く最小の例は次のようになります。

using System.Data;
using System.Data.OleDb;

var dbPath = @"C:\data\sample.accdb";
var cs = $"Provider=Microsoft.ACE.OLEDB.16.0;Data Source={dbPath};Persist Security Info=False;";

using var con = new OleDbConnection(cs);
con.Open();

using var cmd = con.CreateCommand();
cmd.CommandText = "SELECT TOP 10 Id, Name FROM Customers ORDER BY Id DESC";

using var reader = cmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine($"{reader.GetInt32(0)} : {reader.GetString(1)}");
}

設計時に赤い×が付くケースでも、コードでの接続が通るかを先に確認すると切り分けが速くなります。設計時だけが不調なら「デザイナー依存が原因」、実行時も不調なら「ACE / 32bit/64bit / 接続文字列が原因」の可能性が上がります。

OleDb の “Access あるある” を先に潰す(パラメーターと型)

Access + OleDb で地味にハマるのが、SQL のパラメーターの扱いです。SQL Server のような @Name 形式とは違い、OleDb では プレースホルダー(?)が基本になり、パラメーターは「名前」よりも「順番」が重要になります。

using System.Data.OleDb;

var cs = "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=C:\\data\\sample.accdb;";
using var con = new OleDbConnection(cs);
con.Open();

using var cmd = con.CreateCommand();
cmd.CommandText = "INSERT INTO Customers (Name, Age) VALUES (?, ?)";

// パラメーターは「追加した順番」で割り当てられます
cmd.Parameters.AddWithValue("Name", "田中");
cmd.Parameters.AddWithValue("Age", 31);

cmd.ExecuteNonQuery();

この “順番ルール” を知らずに SQL Server の感覚で書くと、値が入れ替わったり、型推論がずれてエラーになったりします。Access を長期運用するなら、AddWithValue の多用を避け、型を明示するのも有効です。

デザイナー(ドラッグ&ドロップ)がうまく動かないときの現実的な回避策

Visual Studio の「データソース」機能は便利ですが、環境やプロジェクト種別によっては Access と相性がよくありません。特に .NET(.NET Core 以降)の WinForms/WPF では、設計時機能が .NET Framework 時代ほど安定しないことがあります。

そこでおすすめなのが、次のように “デザイナー依存を薄くする” 進め方です。

  • フォームにデータを出したいだけなら、OleDbDataAdapter で DataTable を埋めてバインドする
  • CRUD を書くなら、Repository パターンで DB アクセスコードを UI から分離する
  • TableAdapter / 強いデザイナー依存は避け、後から差し替えやすい構造にする

例えば DataGridView に一覧表示するだけなら、次のような最小構成でも十分実用になります。

using System.Data;
using System.Data.OleDb;

var cs = "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=C:\\data\\sample.accdb;";
var dt = new DataTable();

using (var con = new OleDbConnection(cs))
using (var da = new OleDbDataAdapter("SELECT Id, Name, Age FROM Customers ORDER BY Id", con))
{
    da.Fill(dt);
}

// WinForms 例:dataGridView1.DataSource = dt;

この形にしておくと、デザイナーが多少不調でも開発が止まりません。特に “Access を既存資産として使いつつ .NET を最新にしたい” 場合は、設計時ウィザードに全依存しない方がトータルで安定します。

トラブルが続くときのチェックリスト(原因を潰す順番)

ここからは、実際に詰まりやすいポイントを「確認 → 対処」に落とし込んだチェックリストです。上から順に潰すのが近道です。

チェック項目確認ポイントよくある NG対処
SqlClient 依存が混入していないかNuGet 参照、依存プロジェクト、設計時生成コードAccess なのに Microsoft.Data.SqlClient 参照が残っている不要なら削除。必要ならバージョンを統一し、参照の二重化を避ける
System.Data.OleDb の参照csproj に PackageReference があるかOleDb を使うコードを書いたのに参照がなくビルドできないNuGet を追加(例:System.Data.OleDb)
ACE(Access Database Engine)の有無接続時に provider 未登録が出ないかMicrosoft.ACE.OLEDB.xx.0 が “登録されていない”ACE をインストール。Office とビット数が競合する場合は要注意
32bit/64bit の整合アプリのターゲット(x86/x64/Any CPU)と ACE のビット数Any CPU のまま実行して環境依存で落ちるx86 か x64 に固定し、インストール済み ACE と揃える
接続文字列の ProviderMicrosoft.Jet.OLEDB.4.0 を使っていないか64bit 環境で Jet 固定にして接続不可基本は ACE を採用し、Microsoft.ACE.OLEDB... に寄せる
ビルド成果物の汚れ参照の差し替え後に挙動が変わらない古い dll が残っているbin/obj を削除してクリーンビルド(手元で可能な範囲で)

「Failed to load Microsoft.Data.SqlClient version=5.0.0.0…」が出る典型パターン

このエラーは “SqlClient が必要なのに見つからない” という状況なので、次のような状態で発生しやすいです。

パターン:参照している SqlClient の “期待バージョン” がズレている

例えば、あるコンポーネントが Microsoft.Data.SqlClient, Version=5.0.0.0 を要求しているのに、プロジェクトには別メジャー系しか入っていない/逆に入れたつもりが別プロジェクトは古いまま、というズレがあると設計時読み込みで落ちることがあります。

Access を扱うだけなら SqlClient を消す方向が基本ですが、消せない事情がある場合は次の考え方が有効です。

  • ソリューション内で SqlClient のメジャーバージョンを統一する(混在を避ける)
  • 参照元/参照先で 二重に SqlClient を持たないように整理する
  • 依存関係が崩れると復旧に時間がかかるため、DB アクセス層を分ける(Access 用プロジェクトに SqlClient を持ち込まない)

パターン:デザイナー生成コードが SQL Server 前提になっている

DataSet デザイナーや TableAdapter を使っている場合、過去の設定が残って SqlConnection 系の生成コードが入り込み、設計時に SqlClient を読みに行くことがあります。Access を使うプロジェクトであれば、次のように整理すると再発しにくくなります。

  • デザイナー生成コード(.Designer.cs)が SQL Server 向けになっていないか確認する
  • Access 用は OleDbConnection/OleDbDataAdapter に寄せる
  • 将来的な移行も見据えるなら、TableAdapter 依存を減らし “自前の薄いデータアクセス層” に置き換える

.mdb と .accdb:移行を検討した方がよいケース

.mdb は長い歴史があり、既存資産として残っている現場も多い一方で、開発環境やドライバーの都合で “古い形式に引っ張られる” ことがあります。可能であれば .mdb → .accdb の移行を検討すると、詰まりどころが減ることが多いです。

観点.mdb.accdb
主なエンジンJet 系が前提になりやすいACE 前提になりやすい
現代の開発環境との相性環境差が出やすい(特に Jet 固定にした場合)ACE に寄せやすく、ドライバー面の選択肢が比較的広い
移行のハードル既存互換がある一方、ドライバー起因のトラブルが残るファイル形式の変更が発生するが、以後の運用が楽になることが多い

ただし、業務システムで長年運用している Access には “帳票・マクロ・VBA・フォーム” といった周辺資産が紐づいていることもあります。移行は DB ファイルだけでなく、運用・配布・権限も含めて判断してください。

設計面のおすすめ:TableAdapter 依存を減らし、将来の変更に強くする

Visual Studio のデザイナー(DataSet / TableAdapter)は、うまくハマると開発が速い反面、次のようなリスクがあります。

  • 設計時の依存が大きく、環境差(VS バージョン差・拡張機能・SDK)で壊れやすい
  • 自動生成コードが増え、問題の切り分けが難しい
  • DB を Access から別製品へ移行したくなった時に置き換えが重い

Access を使い続ける場合でも、実務では次の “現実的な折衷案” が安定します。

アプローチ:OleDb を薄くラップして使う

Access は “ファイル DB” なので、アプリが直接接続する構造になりがちです。だからこそ、UI と DB アクセスを分けるだけで保守性が一気に上がります。例えば、次のようなメソッドを 1 箇所に集約するだけでも効果があります。

public sealed class AccessDb
{
    private readonly string _connectionString;

    public AccessDb(string path)
    {
        _connectionString = $"Provider=Microsoft.ACE.OLEDB.16.0;Data Source={path};Persist Security Info=False;";
    }

    public DataTable Query(string sql, params OleDbParameter[] parameters)
    {
        var dt = new DataTable();
        using var con = new OleDbConnection(_connectionString);
        using var cmd = new OleDbCommand(sql, con);
        if (parameters != null && parameters.Length > 0)
            cmd.Parameters.AddRange(parameters);

        using var da = new OleDbDataAdapter(cmd);
        da.Fill(dt);
        return dt;
    }
}

この形なら、将来 SQLite や SQL Server に変えるときも、差し替え範囲を限定できます。「デザイナーでフィールドをドラッグして終わり」に比べると最初は少し手間ですが、トラブル対応時間を大幅に減らせるのがメリットです。

アプローチ:Dapper などの軽量 ORM を使う(ただし OleDb の癖は理解する)

Dapper のような軽量 ORM は、SQL を書きつつマッピングだけ楽にしたい場合に向きます。OleDbConnection は IDbConnection なので利用可能ですが、Access(OleDb)は ? パラメーターの順序が重要など癖があります。採用するなら、チーム内で “書き方のルール” を決めておくと事故が減ります。

アプローチ:将来的に DB を置き換える(SQLite / SQL Server Express など)

Access は手軽ですが、同時更新・配布・ロック競合などの運用課題が出やすい面もあります。要件によっては SQLite(ローカル DB)や SQL Server Express(サーバー型)に移行した方が、長期的に安定することもあります。今すぐ移行しない場合でも、DB アクセス層を分離しておくと “いつでも移行できる” 状態を作れます。

最後に:この問題のポイントを一枚で整理

「Failed to load Microsoft.Data.SqlClient version=5.0.0.0…」は派手なエラーですが、やることは次の 3 つに集約できます。

  • Access は SqlClient ではなく OleDb(Jet/ACE)で扱う
  • System.Data.OleDb を参照し、接続文字列を ACE に合わせる
  • 32bit/64bit を揃える。さらに SqlClient が必要な構成ならバージョン混在を解消する

デザイナーが不安定でも、OleDb での接続と最低限のバインディングを押さえれば、開発は前に進められます。Access 資産を活かしつつ .NET を更新したい場合は、まず “SqlClient の道” を断ち切り、OleDb に寄せるところから始めてください。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次