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 例 | 補足 |
|---|---|---|
| .accdb | Provider=Microsoft.ACE.OLEDB.16.0; | 環境により 12.0 の場合もあります(インストール状況に依存)。 |
| .mdb | Provider=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 と揃える |
| 接続文字列の Provider | Microsoft.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 に寄せるところから始めてください。

コメント