レガシーEF6とSystem.Data.SqlClientからMicrosoft Fabric SQL Databaseへ安全に接続する方法|最小改修と長期移行の完全ガイド

既存の .NET Framework(EF6+System.Data.SqlClient)を大きく崩さずに、Microsoft Fabric の SQL Database / Warehouse に“安全に・確実に”つなげるための実践ガイドです。最小改修ルートと将来に耐えるルートを両方示し、接続文字列、EF6 の設定、認証方式、落とし穴、性能・運用までを一気通貫で整理します。

目次

前提とゴール

  • 前提:アプリは .NET Framework(EF6)で稼働中。System.Data.SqlClient を利用。
  • 要件:大規模リファクタリング(EF Core 乗り換え等)は避けたいが、Microsoft Fabric の SQL Database / Warehouse に接続したい。
  • ゴール:短期的には EF6 維持のまま接続を成立させ、長期的には Fabric の新機能に追随できる設計へ段階的に移行できる状態にする。

Fabric 相談窓口(トリアージ)

Fabric(旧 Power BI Fabric)の仕様や既知事象は、汎用 Q&A では対応範囲外の場合があります。製品固有の挙動・制限・最新の既知事象は、Microsoft Fabric コミュニティ(旧 Power BI フォーラム)が最短経路です。運用で困ったらまずここに集約する体制を作ると解決が早くなります。

アーキテクチャと接続方式の全体像

Fabric の SQL Database / Warehouse は TDS(Tabular Data Stream)互換の SQL エンドポイントを提供します。ADO.NET(SqlClient)および EF6 から接続できますが、ドライバの世代差とFabric 固有の未対応機能に注意が必要です。以下は現実的なオプション比較です。

方法現実度主なメリット主な制約 / 注意点
System.Data.SqlClient(現状維持)△(限定的動作)コード改修が最小限一部の認証/暗号化/TDS 拡張が古く、Fabric 側の機能に追いつかない可能性。AAD 認証ではパラメータ差異に注意。高負荷時の TLS/接続再利用で不利。
Microsoft.Data.SqlClient 5.x 以降 + EF6○(推奨する最小改修)最新 TLS と AAD 認証、Always Encrypted などに追随。接続安定性・回復性が向上。NuGet と設定の置き換えが必要。providerName と実行戦略の再設定を忘れない。
EF Core 8 以降 + Microsoft.Data.SqlClient◎(長期推奨)Fabric の新機能へ追随しやすく、パフォーマンス/回復性/診断性が高い。モデル等の大規模リファクタリングが必要。短期導入は難易度高。
ODBC / JDBC ブリッジ△ドライバ単位でのサポートを活用できる場合あり。ADO.NET 経由は煩雑になりがち。EF6 連携では利点が薄い。

最小改修での接続成立(Microsoft.Data.SqlClient + EF6 維持)

多くの現場で最初の壁は「EF6 のまま AAD 認証と暗号化要件を満たしてつなぐ」ことです。以下の順で進めると移行の摩擦が最小です。

NuGet の置き換え

  1. (可能なら)System.Data.SqlClient への直接参照を外します。
  2. Microsoft.Data.SqlClient(5.x 以降) を追加します。
  3. EF6 継続利用のため EntityFramework6.SqlServer(6.5 以降) を追加します。これは EF6 と Microsoft.Data.SqlClient の間をつなぐプロバイダーです。

App.config / Web.config の更新

EF6 で Microsoft.Data.SqlClient を使うには、接続文字列とプロバイダー登録を合わせます。

<configuration>
  <connectionStrings>
    <add name="FabricConnection"
         connectionString="Server=tcp:{Fabric ポータルで表示されるサーバー名};
                           Initial Catalog={SQL Database or Warehouse 名};
                           Encrypt=True;
                           TrustServerCertificate=False;
                           MultipleActiveResultSets=True"
         providerName="Microsoft.Data.SqlClient" />
  </connectionStrings>

  <system.data>
    <DbProviderFactories>
      <remove invariant="Microsoft.Data.SqlClient" />
      <add name="Microsoft.Data.SqlClient"
           invariant="Microsoft.Data.SqlClient"
           description=".NET Framework Data Provider for Microsoft SQL Server"
           type="Microsoft.Data.SqlClient.SqlClientFactory, Microsoft.Data.SqlClient" />
    </DbProviderFactories>
  </system.data>
</configuration>
  • Server は必ず Fabric ポータルの「接続」画面で案内される値を使用してください(環境によりドメイン名が異なります)。
  • オンプレや古い .NET Framework では DbProviderFactories の登録が必要になる場合があります。

認証方式(Microsoft Entra ID)

Fabric では Azure SQL と同様に Entra ID(旧 Azure AD)認証が第一選択です。Microsoft.Data.SqlClient 側の書式は次の通りです。

用途接続文字列例(主要部分)備考
ユーザー対話(運用/管理者ツール)Authentication=Active Directory Interactive;ブラウザでの対話ログイン。テストや小規模ツールに向く。
マネージド ID(Azure VM/App)Authentication=Active Directory Managed Identity;最も運用が楽。ユーザー割当 MI の場合は User Id={clientId} を追加。
アプリ登録(クライアント資格情報)Authentication=Active Directory Service Principal; User ID={appId}; Password={secret};シークレットまたは証明書。資格情報の保護に注意。
トークン直渡し(接続文字列は通常通り) + SqlConnection.AccessToken に設定後述コードの通り。MSAL/Azure.Identity で取得したアクセストークンを注入。

旧来の Authentication=Active Directory Password はレガシー互換の選択肢です。非推奨の方向であり、条件によりブロックされる場合があります。長期運用では Managed Identity か Service Principal を選びましょう。

アクセストークン直渡し(EF6 での実装例)

EF6 は DbConnection をそのまま受け取れるため、Microsoft.Data.SqlClient の SqlConnection に AccessToken を設定してコンテキストへ渡す方法がシンプルです。

using System;
using System.Data.Entity;
using Microsoft.Data.SqlClient;
// Token 取得は Azure.Identity もしくは MSAL を利用(例では Azure.Identity)
using Azure.Identity;
using Azure.Core;

public class FabricDbContext : DbContext
{
    public FabricDbContext(SqlConnection conn) : base(conn, contextOwnsConnection: false) { }
    // DbSet<...> ...
}

public static class FabricDbContextFactory
{
    private const string Scope = "https://database.windows.net//.default";

    public static FabricDbContext Create()
    {
        var cs = System.Configuration.ConfigurationManager
                 .ConnectionStrings["FabricConnection"].ConnectionString;

        var conn = new SqlConnection(cs);

        // マネージド ID / ワークロード ID 等で統一的にトークン取得
        var credential = new DefaultAzureCredential();
        var token = credential.GetToken(new TokenRequestContext(new[] { Scope }));
        conn.AccessToken = token.Token;

        // 必要に応じて接続回復性/タイムアウトを調整
        conn.FireInfoMessageEventOnUserErrors = true;

        return new FabricDbContext(conn);
    }
}

EF6 の実行戦略(接続回復性)設定

Fabric では短時間のスロットリングやネットワーク揺らぎに遭遇することがあります。EF6 の SqlAzureExecutionStrategy を有効化して再試行を自動化します。

using System.Data.Entity;
using System.Data.Entity.SqlServer;

public class EfConfiguration : DbConfiguration
{
    public EfConfiguration()
    {
        // Microsoft.Data.SqlClient 用の実行戦略(EF6 6.5+)
        SetExecutionStrategy("Microsoft.Data.SqlClient",
            () => new SqlAzureExecutionStrategy(maxRetryCount: 5, maxDelay: TimeSpan.FromSeconds(30)));
    }
}

上記クラスをアセンブリに含め、任意のコンテキストから読み込まれるようにしておくと安全です。

System.Data.SqlClient のまま試す場合の要点

  • TLS/暗号化:Encrypt=True; TrustServerCertificate=False; を徹底します。古い OS / ランタイムでは TLS 構成の影響で「プレログイン失敗」になることがあります。
  • AAD パラメーター:古い System.Data.SqlClient は Authentication キーワードに対応していない版があります。この場合は接続文字列での AAD 指示ができず、実質不可になることがあります。
  • 機能差異:MARS/一部の TDS 機能、Always Encrypted、最新のトレース/診断は未対応です。問題が出たら素直に Microsoft.Data.SqlClient に切り替えるのが近道です。

Fabric 向けの機能差分(EF6 観点)

カテゴリ推奨/可否解説
DDL(マイグレーション)△(要検証)EF6 の自動マイグレーションを常用しない方が安全。スキーマ変更は T-SQL スクリプト/パイプラインで適用し、EF6 側はコードファースト生成の追随にとどめる運用が堅実。
大量バルクロード○SqlBulkCopy でテーブルロックと明示マッピングを使う。EF6 の SaveChanges() 連打は避ける。
トランザクション○(ローカル) / ×(DTC)分散トランザクション(DTC)は不可。BeginTransaction() を基本にする。
CTAS / 一時テーブル△CTAS は Warehouse でよく使うが、EF6 経由では生 SQL に逃がす。コンテキストに依存しない ADO.NET 実行で確実に。
Security(Always Encrypted)○Microsoft.Data.SqlClient 5.x 以降で対応。ドライバ側の設定・キー管理が前提。EF6 でも使用可。

接続文字列の実用テンプレート

サーバー名は Fabric ポータルの「接続」画面で表示される値をそのまま貼り付けます。以下は用途別に差し替えて使えるテンプレートです。

対話ログイン(検証)

Server=tcp:{server-from-portal},1433;
Initial Catalog={db-or-warehouse};
Encrypt=True;TrustServerCertificate=False;
Authentication=Active Directory Interactive;
MultipleActiveResultSets=True;
Application Name={your-app};

マネージド ID(本番運用)

Server=tcp:{server-from-portal},1433;
Initial Catalog={db-or-warehouse};
Encrypt=True;TrustServerCertificate=False;
Authentication=Active Directory Managed Identity;
MultipleActiveResultSets=True;

サービス プリンシパル(バッチ/ETL)

Server=tcp:{server-from-portal},1433;
Initial Catalog={db-or-warehouse};
Encrypt=True;TrustServerCertificate=False;
Authentication=Active Directory Service Principal;
User ID={appId};Password={secret};
MultipleActiveResultSets=True;

既存コードへの最小インパクト移行チェックリスト

  • NuGet:Microsoft.Data.SqlClient と EntityFramework6.SqlServer を追加。System.Data.SqlClient の暗黙参照を外す。
  • providerName:System.Data.SqlClient → Microsoft.Data.SqlClient に変更。
  • DbProviderFactories:.NET Framework の場合は登録エントリを明示(上記例)。
  • EF6 実行戦略:SqlAzureExecutionStrategy を Microsoft.Data.SqlClient に紐づけて登録。
  • 接続タイムアウト:Connect Timeout=30 を基準に、初期アクセス重い環境では 60–120 を検討。
  • MARS:MultipleActiveResultSets=True を必要時のみ有効化(同時に多くの DataReader を開かない設計が理想)。
  • Pooling:高並列なら Max Pool Size の調整、Min Pool Size の事前ウォームアップを検討。
  • ログ:EF6 の SQL ログとドライバのイベントログ(EventSource)を有効化し、再試行・スロットリングを観測。

トラブルシューティング(よくあるエラーと解決策)

症状 / メッセージ主因対処
Keyword not supported: 'authentication'古い System.Data.SqlClient を使用Microsoft.Data.SqlClient に切り替える。EF6 は EntityFramework6.SqlServer を導入。
A connection was successfully established ... pre-login handshakeTLS バージョン/暗号スイート不整合OS/TLS 更新、Encrypt=True;TrustServerCertificate=False を明示、ドライバを最新化。
Login failed for user '<token-identified principal>'テナント誤り / RBAC 不足正しいテナントでトークンを取得。Fabric での DB 権限(接続/読み取り/書き込み)を付与。
Cannot open server ... requested by the loginサーバー名/DB 名の誤りFabric ポータルの「接続」情報からサーバーと DB 名を再確認。
The server was not found or was not accessibleネットワーク制限/ファイアウォール送信元のアウトバウンド許可、Private/パブリック アクセス設定、プロキシ越えを確認。
Provider not found / ProviderIncompatibleExceptionEF6 側プロバイダー未登録EntityFramework6.SqlServer の導入と providerName の見直し。
CTAS/バルクロードでのタイムアウトEF 経由の実行戦略/バッチ設計が不適切ADO.NET 生実行に切り替え、タイムアウト/バッチサイズを調整。必要に応じてステージングテーブルを併用。

性能チューニングの実践ポイント

  • クエリ最適化:EF6 の生成 SQL をログで確認し、必要に応じて AsNoTracking()、投影(Select)で列を絞る。
  • 変更検出の最適化:大量 INSERT/UPDATE 前は Configuration.AutoDetectChangesEnabled = false。バッチ単位で DetectChanges() を明示。
  • バルクロード:SqlBulkCopy で BatchSize と NotifyAfter を設定し、進捗と圧迫を両立。
  • 接続回復性:SqlAzureExecutionStrategy を必ず有効化。タイムアウトは冗長にし過ぎない(リトライと併用)。
  • 並列度:プールサイズとアプリ側スレッドプールを合わせて調整。過剰並列は逆効果。

セキュリティ実装のコツ

  • 資格情報の外だし:接続文字列は ユーザーシークレット/KeyVault/Config Transform で管理。構成の標準化が最優先。
  • 最小特権:読み取り専用アプリには db_datareader 相当権限のみを付与。管理系は別アプリ登録に分離。
  • Always Encrypted:機密列に適用。パフォーマンス影響と索引制約を理解し、必要列に限定。
  • 監査/診断:アプリ側の相関 ID(Application Name)とサーバー側のログを結び、事後解析を容易に。

EF6 から EF Core への段階移行(ロードマップ)

短期は EF6 を維持しつつ、次の観点で「後戻りしない」コードに整えます。

  1. ドメイン分離:リポジトリ層/サービス層で EF 依存を局所化。生 SQL と EF を併用できる設計に。
  2. クエリ見直し:LINQ の書き癖(ナビゲーションの多段展開等)を整理し、EF Core でも同等に書ける形へ寄せる。
  3. 移行優先度:書込み負荷の高い箇所、複雑なトランザクション、バッチ/ETL は EF Core 先行移行の候補に。
  4. 並行稼働:一部コンテキストは EF6、別コンテキストは EF Core とし、実稼働での段階切替に耐える構成に。

サンプル:EF6 + Microsoft.Data.SqlClient での基本 CRUD

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class AppDbContext : DbContext
{
public AppDbContext(SqlConnection conn) : base(conn, false) { }
public DbSet Customers { get; set; }
}

public class Repository
{
public void CreateCustomer(string name)
{
using (var ctx = FabricDbContextFactory.Create())
{
using (var tx = ctx.Database.BeginTransaction())
{
ctx.Set().Add(new Customer { Name = name });
ctx.SaveChanges();
tx.Commit();
}
}
}


public IEnumerable<Customer> GetAll()
{
    using (var ctx = FabricDbContextFactory.Create())
    {
        ctx.Configuration.AutoDetectChangesEnabled = false;
        return ctx.Set<Customer>().AsNoTracking().ToList();
    }
}


} 

実運用チェックリスト(デプロイ前)

  • 接続先情報(サーバー名/DB 名/テナント)が 構成ファイルに統一され、環境ごとの変換が自動化されている。
  • 実行戦略とタイムアウト、リトライポリシーを ステージングで検証済み。
  • アプリ ID またはマネージド ID に必要最小限のロールが割り当て済み。
  • 障害注入(ネットワーク切断/スロットリング遅延)で 自動回復と 冪等性が確認できている。
  • 監査・トレースの収集基盤(アプリケーションログ + サーバーログ)が確立されている。

ケース別の設計指針(素早い判断に)

状況選択肢理由
まずはエラーを止めたいMicrosoft.Data.SqlClient 5.x 以降 + EF6最小改修で TLS/AAD/接続回復性を獲得できる。多くの互換問題が解消。
Fabric の新機能を積極活用したいEF Core 8 以降への段階移行Direct Lake/キャッシュ/診断など中長期の追随性が高い。
ETL/集約主体のアプリEF6 + ADO.NET 併用(Bulk/CTAS は生 SQL)EF の抽象化は読み取りに残し、書き込みは専用パスで高速化。

まとめ(結論)

短期:大規模なリファクタリングを避ける要望には、Microsoft.Data.SqlClient 5.x 以降 + EF6 への置き換えが最も現実的です。接続文字列の providerName と認証パラメーター、EF6 の実行戦略を整えるだけで、多くの接続/安定性の課題が解消します。

長期:Fabric の機能拡張速度を考えると、将来は EF Core 8 以降への段階移行が投資対効果に優れます。今は「NuGet と構成の差し替え」で足場を作り、リポジトリ層の分離や生 SQL パスの導入で、後日の移行コストを最小化しましょう。

困ったら:Fabric 固有の仕様・挙動は、製品コミュニティでのナレッジが最も早く蓄積されます。運用フローに「まずコミュニティで既知事象を確認する」を組み込み、問題の切り分けを高速化してください。


付録:トラブル時のチェックフロー(現場用)

  1. 接続情報:サーバー名/DB 名を Fabric ポータルの「接続」からコピーしたか。
  2. ドライバ:Microsoft.Data.SqlClient 5.x 以降になっているか。
  3. EF6 プロバイダー:EntityFramework6.SqlServer が入っているか。providerName は Microsoft.Data.SqlClient か。
  4. 暗号化:Encrypt=True;TrustServerCertificate=False が明示されているか。
  5. 認証:運用形態に合った AAD 方式(MI/SP/Interactive/AccessToken)を選んだか。
  6. 権限:接続/読み取り/書き込みのロールが正しく割り当てられているか。
  7. ネットワーク:送信元のアウトバウンド許可、必要なプロキシ例外が設定されているか。
  8. 再試行:SqlAzureExecutionStrategy を設定したか。タイムアウトとセットで調整したか。

付録:構成差分の自動化例(Web.config Transform)

&lt;connectionStrings xdt:Transform="Replace"&gt;
  &lt;add name="FabricConnection"
       connectionString="Server=tcp:#{FabricServer}#;
                         Initial Catalog=#{FabricDb}#;
                         Encrypt=True;TrustServerCertificate=False;
                         Authentication=Active Directory Managed Identity;
                         MultipleActiveResultSets=True"
       providerName="Microsoft.Data.SqlClient" /&gt;
&lt;/connectionStrings&gt;

CI/CD で環境変数を注入するだけで、安全に接続先を切り替えられます。

付録:SqlBulkCopy のスケルトン(EF6 併用)

public async Task BulkInsertAsync(DataTable table, string destTable, CancellationToken ct)
{
    var cs = ConfigurationManager.ConnectionStrings["FabricConnection"].ConnectionString;
    using var conn = new SqlConnection(cs);


// 必要ならトークン直渡し(前述の取得コードを再利用)
// conn.AccessToken = ...

await conn.OpenAsync(ct);

using var bulk = new SqlBulkCopy(conn,
    SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.CheckConstraints,
    externalTransaction: null)
{
    DestinationTableName = destTable,
    BatchSize = 5000,
    BulkCopyTimeout = 600,
    NotifyAfter = 10000
};

foreach (DataColumn col in table.Columns)
    bulk.ColumnMappings.Add(col.ColumnName, col.ColumnName);

await bulk.WriteToServerAsync(table, ct);


} 

最後に

レガシー .NET の「動いているものを壊さない」という要件と、Fabric の「進化が速い」現実は両立できます。まずは Microsoft.Data.SqlClient + EF6 で接続を安定させ、性能/回復性/セキュリティを一段底上げ。そのうえで、負荷の高い領域から EF Core に段階移行する二段構えが、最短で最小のリスクです。

この記事を書いた人

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

コメント

コメントする

目次