Microsoft Fabric Data Engineering 用の Microsoft ADO.NET ドライバー (プレビュー)

Important

この機能は プレビュー段階です

ADO.NET は、.NET エコシステムで広く採用されているデータ アクセス テクノロジであり、アプリケーションがデータベースやビッグ データ プラットフォームのデータに接続して操作できるようにします。

Microsoft ADO.NET Driver for Fabric Data Engineering を使用すると、標準の ADO.NET パターンの信頼性とシンプルさで、Microsoft Fabric の Spark ワークロードを接続、クエリ、管理できます。 Microsoft Fabric の Livy API 上に構築されたドライバーは、使い慣れた DbConnectionDbCommand、および DbDataReader 抽象化を使用して、セキュリティで保護された柔軟な Spark SQL 接続を .NET アプリケーションに提供します。

主要な機能

  • ADO.NET 準拠: ADO.NET 抽象化の完全な実装 (DbConnectionDbCommandDbDataReaderDbParameterDbProviderFactory)
  • Microsoft Entra ID 認証: Azure CLI、対話型ブラウザー、クライアント資格情報、証明書ベース、アクセス トークン認証を含む複数の認証フロー
  • Spark SQL ネイティブ クエリのサポート: パラメーター化されたクエリを使用した Spark SQL ステートメントの直接実行
  • 包括的なデータ型のサポート: 複合型 (ARRAY、MAP、STRUCT) を含むすべての Spark SQL データ型のサポート
  • 接続プール: パフォーマンスを向上するための組み込みの接続プール管理
  • セッションの再利用: スタートアップ待ち時間を短縮する効率的な Spark セッション管理
  • 非同期プリフェッチ: 大きな結果セットでパフォーマンスを向上させるバックグラウンド データの読み込み
  • 自動再接続: 接続エラー後のセッションの自動回復

オープン ソースの Apache Spark では、データベースとスキーマが同義で使用されます。 たとえば、Fabric Notebook で SHOW SCHEMAS または SHOW DATABASES を実行すると、Lakehouse 内のすべてのスキーマの一覧という同じ結果が返されます。

前提条件

Microsoft ADO.NET Driver for Microsoft Fabric Data Engineering を使用する前に、次のことを確認してください。

  • .NET ランタイム: .NET 8.0 以降
  • Microsoft Fabric Access: データ エンジニアリング機能を備えた Microsoft Fabric ワークスペースへのアクセス
  • Azure Entra ID 資格情報: 認証に適した資格情報
  • ワークスペース ID とレイクハウス ID: Fabric ワークスペースとレイクハウスの GUID 識別子
  • Azure CLI (省略可能): Azure CLI 認証方法に必要

ダウンロード、インクルード、参照、検証

NuGet パッケージのダウンロード

Microsoft ADO.NET Driver for Microsoft Fabric Data Engineering バージョン 1.0.0 はパブリック プレビュー段階であり、これらのダウンロード センターのリンクからダウンロードできます。

プロジェクトで NuGet パッケージを参照する

ダウンロードした NuGet パッケージをプロジェクトに含め、パッケージの参照をプロジェクト ファイルに追加します。

<ItemGroup>
    <PackageReference Include="Microsoft.Spark.Livy.AdoNet" Version="1.0.0" />
</ItemGroup>

インストールを検証する

含めて参照した後、プロジェクトでパッケージが使用可能であることを確認します。

using Microsoft.Spark.Livy.AdoNet;

// Verify the provider is registered
var factory = LivyProviderFactory.Instance;
Console.WriteLine($"Provider: {factory.GetType().Name}");

クイックスタートの例

using Microsoft.Spark.Livy.AdoNet;

// Connection string with required parameters
string connectionString =
    "Server=https://api.fabric.microsoft.com/v1;" +
    "SparkServerType=Fabric;" +
    "FabricWorkspaceID=<workspace-id>;" +
    "FabricLakehouseID=<lakehouse-id>;" +
    "AuthFlow=AzureCli;";

// Create and open connection
using var connection = new LivyConnection(connectionString);
await connection.OpenAsync();

Console.WriteLine("Connected successfully!");

// Execute a query
using var command = connection.CreateCommand();
command.CommandText = "SELECT 'Hello from Fabric!' as message";

using var reader = await command.ExecuteReaderAsync();
if (await reader.ReadAsync())
{
    Console.WriteLine(reader.GetString(0));
}

接続文字列の形式

基本形式

Microsoft ADO.NET ドライバーでは、標準の ADO.NET 接続文字列形式が使用されます。

Parameter1=Value1;Parameter2=Value2;...

必須のパラメーター

パラメーター 説明
Server Microsoft Fabric API エンドポイント https://api.fabric.microsoft.com/v1
SparkServerType サーバーの種類の識別子 Fabric
FabricWorkspaceID Microsoft Fabric ワークスペース識別子 (GUID) <workspace-id>
FabricLakehouseID Microsoft Fabric Lakehouse 識別子 (GUID) <lakehouse-id>
AuthFlow 認証方法 AzureCliBrowserBasedClientSecretCredentialClientCertificateCredentialAuthAccessTokenFileToken

省略可能なパラメーター

接続の設定

パラメーター タイプ デフォルト 説明
LivySessionTimeoutSeconds 整数 60 セッションの作成を待機する時間 (秒単位)
LivyStatementTimeoutSeconds 整数 600 ステートメントの実行を待機する時間 (秒単位)
SessionName (auto) Spark セッションのカスタム名
AutoReconnect ブール値 false セッションの自動回復を有効にする

接続プールの設定

パラメーター タイプ デフォルト 説明
ConnectionPoolEnabled ブール値 true 接続プールを有効にする
MinPoolSize 整数 1 プール内の最小接続数
MaxPoolSize 整数 20 プール内の最大接続数
ConnectionMaxIdleTimeMs 整数 1800000 接続がリサイクルされるまでの最大アイドル時間 (30 分)
MaxLifetimeMs 整数 3600000 プールされた接続の最大有効期間 (60 分)
ValidateConnections ブール値 true 使用する前に接続を検証する
ValidationTimeoutMs 整数 5000 接続検証のタイムアウト

ログ記録の設定

パラメーター タイプ デフォルト 説明
LogLevel Information ログ レベル: TraceDebugInformationWarningError
LogFilePath (なし) ファイルベースのロギング用パス

ドライバー間のエイリアス: ドライバーは、ネイティブの ADO.NET 名に加えて、JDBC と ODBC のプロパティ名を受け入れます (たとえば、 WorkspaceIdFabricWorkspaceIDにマップされ、 LakehouseIdFabricLakehouseIDにマップされます)。 すべてのプロパティ名では大文字と小文字が区別されません。

接続文字列の例

基本接続 (Azure CLI 認証)

Server=https://api.fabric.microsoft.com/v1;SparkServerType=Fabric;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=AzureCli

接続プールのオプションを利用する

Server=https://api.fabric.microsoft.com/v1;SparkServerType=Fabric;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=AzureCli;ConnectionPoolEnabled=true;MinPoolSize=2;MaxPoolSize=10

自動再接続とログ記録を使用する

Server=https://api.fabric.microsoft.com/v1;SparkServerType=Fabric;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=AzureCli;AutoReconnect=true;LogLevel=Debug

認証

Microsoft ADO.NET ドライバーでは、Microsoft Entra ID (旧称 Azure Active Directory) を使用した複数の認証方法がサポートされています。 認証は、接続文字列の AuthFlow パラメーターを使用して構成されます。

認証方法

AuthFlow 値 説明 最適な対象者
AzureCli Azure CLI のキャッシュされた資格情報を使用する 開発とテスト
BrowserBased 対話型ブラウザー ベースの認証 ユーザー向けアプリケーション
ClientSecretCredential クライアント シークレットを含むサービス プリンシパル 自動化サービス、バックグラウンド処理
ClientCertificateCredential 証明書付きサービス プリンシパル エンタープライズ アプリケーション
AuthAccessToken 事前に取得されたベアラー アクセス トークン カスタム認証シナリオ

Azure CLI 認証

最適な用途: 開発とテスト

string connectionString =
    "Server=https://api.fabric.microsoft.com/v1;" +
    "SparkServerType=Fabric;" +
    "FabricWorkspaceID=<workspace-id>;" +
    "FabricLakehouseID=<lakehouse-id>;" +
    "AuthFlow=AzureCli;";

using var connection = new LivyConnection(connectionString);
await connection.OpenAsync();

前提条件:

  • Azure CLI がインストールされている: az --version
  • ログイン: az login

対話型ブラウザーの認証

最適な用途: ユーザー向けのアプリケーション

string connectionString =
    "Server=https://api.fabric.microsoft.com/v1;" +
    "SparkServerType=Fabric;" +
    "FabricWorkspaceID=<workspace-id>;" +
    "FabricLakehouseID=<lakehouse-id>;" +
    "AuthFlow=BrowserBased;" +
    "AuthTenantID=<tenant-id>;";

using var connection = new LivyConnection(connectionString);
await connection.OpenAsync(); // Opens browser for authentication

動作:

  • ユーザー認証用のブラウザー ウィンドウを開きます
  • 資格情報は後続の接続用にキャッシュされます

クライアント資格情報 (サービス プリンシパル) 認証

最適: 自動化されたサービスとバックグラウンドの作業

string connectionString =
    "Server=https://api.fabric.microsoft.com/v1;" +
    "SparkServerType=Fabric;" +
    "FabricWorkspaceID=<workspace-id>;" +
    "FabricLakehouseID=<lakehouse-id>;" +
    "AuthFlow=ClientSecretCredential;" +
    "AuthTenantID=<tenant-id>;" +
    "AuthClientID=<client-id>;" +
    "AuthClientSecret=<client-secret>;";

using var connection = new LivyConnection(connectionString);
await connection.OpenAsync();

必須パラメーター:

  • AuthTenantID: Azure テナント ID
  • AuthClientID: Microsoft Entra ID からのアプリケーション (クライアント) ID
  • AuthClientSecret: Microsoft Entra ID からのクライアント シークレット

証明書ベースの認証

最適な対象: 証明書ベースの認証を必要とするエンタープライズ アプリケーション

string connectionString =
    "Server=https://api.fabric.microsoft.com/v1;" +
    "SparkServerType=Fabric;" +
    "FabricWorkspaceID=<workspace-id>;" +
    "FabricLakehouseID=<lakehouse-id>;" +
    "AuthFlow=ClientCertificateCredential;" +
    "AuthTenantID=<tenant-id>;" +
    "AuthClientID=<client-id>;" +
    "AuthCertificatePath=C:\\certs\\mycert.pfx;" +
    "AuthCertificatePassword=<password>;";

using var connection = new LivyConnection(connectionString);
await connection.OpenAsync();

必須パラメーター:

  • AuthTenantID: Azure テナント ID
  • AuthClientID: アプリケーション (クライアント) ID
  • AuthCertificatePath: PFX/PKCS12 証明書ファイルへのパス
  • AuthCertificatePassword: 証明書パスワード

アクセス トークン認証

最適な用途: カスタム認証シナリオ

// Acquire token through your custom mechanism
string accessToken = await AcquireTokenFromCustomSourceAsync();

string connectionString =
    "Server=https://api.fabric.microsoft.com/v1;" +
    "SparkServerType=Fabric;" +
    "FabricWorkspaceID=<workspace-id>;" +
    "FabricLakehouseID=<lakehouse-id>;" +
    "AuthFlow=AuthAccessToken;" +
    $"AuthAccessToken={accessToken};";

using var connection = new LivyConnection(connectionString);
await connection.OpenAsync();

コード内のパスワード、キー、シークレット、トークン、証明書などの資格情報をハードコーディングしないことを強くお勧めします。 代わりに、Azure Key Vault を使用してこれらの値を安全に格納し、実行時に取得します。

使用例

基本的な接続とクエリ

using Microsoft.Spark.Livy.AdoNet;

string connectionString =
    "Server=https://api.fabric.microsoft.com/v1;" +
    "SparkServerType=Fabric;" +
    "FabricWorkspaceID=<workspace-id>;" +
    "FabricLakehouseID=<lakehouse-id>;" +
    "AuthFlow=AzureCli;";

using var connection = new LivyConnection(connectionString);
await connection.OpenAsync();

Console.WriteLine($"Connected! Server version: {connection.ServerVersion}");

// Execute a query
using var command = connection.CreateCommand();
command.CommandText = "SELECT * FROM employees LIMIT 10";

using var reader = await command.ExecuteReaderAsync();

// Print column names
for (int i = 0; i < reader.FieldCount; i++)
{
    Console.Write($"{reader.GetName(i)}\t");
}
Console.WriteLine();

// Print rows
while (await reader.ReadAsync())
{
    for (int i = 0; i < reader.FieldCount; i++)
    {
        Console.Write($"{reader.GetValue(i)}\t");
    }
    Console.WriteLine();
}

パラメーター化されたクエリ

using var command = connection.CreateCommand();
command.CommandText = "SELECT * FROM orders WHERE order_date >= @startDate AND status = @status";

// Add parameters
command.Parameters.AddWithValue("@startDate", new DateTime(2024, 1, 1));
command.Parameters.AddWithValue("@status", "completed");

using var reader = await command.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
    Console.WriteLine($"Order: {reader["order_id"]}, Total: {reader["total"]:C}");
}

単一値の ExecuteScalar

using var command = connection.CreateCommand();
command.CommandText = "SELECT COUNT(*) FROM customers";

var count = await command.ExecuteScalarAsync();
Console.WriteLine($"Total customers: {count}");

DML 操作の ExecuteNonQuery

// INSERT
using var insertCommand = connection.CreateCommand();
insertCommand.CommandText = @"
    INSERT INTO employees (id, name, department, salary)
    VALUES (100, 'John Doe', 'Engineering', 85000)";

int rowsAffected = await insertCommand.ExecuteNonQueryAsync();
Console.WriteLine($"Inserted {rowsAffected} row(s)");

// UPDATE
using var updateCommand = connection.CreateCommand();
updateCommand.CommandText = "UPDATE employees SET salary = 90000 WHERE id = 100";

rowsAffected = await updateCommand.ExecuteNonQueryAsync();
Console.WriteLine($"Updated {rowsAffected} row(s)");

// DELETE
using var deleteCommand = connection.CreateCommand();
deleteCommand.CommandText = "DELETE FROM employees WHERE id = 100";

rowsAffected = await deleteCommand.ExecuteNonQueryAsync();
Console.WriteLine($"Deleted {rowsAffected} row(s)");

大規模な結果セットを扱う

using var command = connection.CreateCommand();
command.CommandText = "SELECT * FROM large_table";

using var reader = await command.ExecuteReaderAsync();

int rowCount = 0;
while (await reader.ReadAsync())
{
    // Process each row
    ProcessRow(reader);
    rowCount++;

    if (rowCount % 10000 == 0)
    {
        Console.WriteLine($"Processed {rowCount} rows...");
    }
}

Console.WriteLine($"Total rows processed: {rowCount}");

スキーマ検出

// List all tables
using var showTablesCommand = connection.CreateCommand();
showTablesCommand.CommandText = "SHOW TABLES";

using var tablesReader = await showTablesCommand.ExecuteReaderAsync();
Console.WriteLine("Available tables:");
while (await tablesReader.ReadAsync())
{
    Console.WriteLine($"  {tablesReader.GetString(0)}");
}

// Describe table structure
using var describeCommand = connection.CreateCommand();
describeCommand.CommandText = "DESCRIBE employees";

using var schemaReader = await describeCommand.ExecuteReaderAsync();
Console.WriteLine("\nTable structure for 'employees':");
while (await schemaReader.ReadAsync())
{
    Console.WriteLine($"  {schemaReader["col_name"]}: {schemaReader["data_type"]}");
}

LivyConnectionStringBuilder の使用

using Microsoft.Spark.Livy.AdoNet;

var builder = new LivyConnectionStringBuilder
{
    Server = "https://api.fabric.microsoft.com/v1",
    SparkServerType = "Fabric",
    FabricWorkspaceID = "<workspace-id>",
    FabricLakehouseID = "<lakehouse-id>",
    AuthFlow = "AzureCli",
    ConnectionPoolingEnabled = true,
    MinPoolSize = 2,
    MaxPoolSize = 10,
    ConnectionTimeout = 60
};

using var connection = new LivyConnection(builder.ConnectionString);
await connection.OpenAsync();

DbProviderFactory の使用

using System.Data.Common;
using Microsoft.Spark.Livy.AdoNet;

// Register the provider factory (typically done at application startup)
DbProviderFactories.RegisterFactory("Microsoft.Spark.Livy.AdoNet", LivyProviderFactory.Instance);

// Create connection using factory
var factory = DbProviderFactories.GetFactory("Microsoft.Spark.Livy.AdoNet");

using var connection = factory.CreateConnection();
connection.ConnectionString = connectionString;

await connection.OpenAsync();

using var command = factory.CreateCommand();
command.Connection = connection;
command.CommandText = "SELECT * FROM employees LIMIT 5";

using var reader = await command.ExecuteReaderAsync();
// Process results...

データ型マッピング

ドライバーは、Spark SQL データ型を .NET 型にマップします。

Spark SQL の種類 .NET 型 DbType
BOOLEAN bool ブール値
タイニーイント (TINYINT) sbyte SByte
SMALLINT short Int16
INT int Int32
BIGINT long Int64
FLOAT float 未婚
DOUBLE double Double
DECIMAL(p,s) decimal 10 進法
STRING string
VARCHAR(n) string
CHAR(n) string
バイナリ byte[] Binary
DATE DateTime 日付
TIMESTAMP DateTime 日時
ARRAY<T> T[] または string (JSON) オブジェクト
MAP<K,V> Dictionary<K,V> または string (JSON) オブジェクト
STRUCT object または string (JSON) オブジェクト

複合型の取り扱い

複合型 (ARRAY、MAP、STRUCT) は、既定で JSON 文字列として返されます。

using System.Text.Json;
using System.Collections.Generic;

using var command = connection.CreateCommand();
command.CommandText = "SELECT array_column, map_column, struct_column FROM complex_table LIMIT 1";

using var reader = await command.ExecuteReaderAsync();
if (await reader.ReadAsync())
{
    // Complex types returned as JSON strings
    string arrayJson = reader.GetString(0);  // e.g., "[1, 2, 3]"
    string mapJson = reader.GetString(1);    // e.g., "{\"key\": \"value\"}"
    string structJson = reader.GetString(2); // e.g., "{\"field1\": 1, \"field2\": \"text\"}"

    // Parse with System.Text.Json
    var array = JsonSerializer.Deserialize<int[]>(arrayJson);
    var map = JsonSerializer.Deserialize<Dictionary<string, string>>(mapJson);
}

Troubleshooting

このセクションでは、Microsoft ADO.NET Driver for Microsoft Fabric Data Engineering を使用するときに発生する可能性がある一般的な問題を解決するためのガイダンスを提供します。

一般的な問題

次のセクションでは、一般的な問題とその解決策について説明します。

接続の失敗

問題: Microsoft Fabric に接続できない

解決策:

  1. FabricWorkspaceIDFabricLakehouseIDが正しい GUID であることを確認する
  2. Azure CLI 認証を確認します。 az account show
  3. 適切な Fabric ワークスペースのアクセス許可があることを確認する
  4. へのネットワーク接続を確認する api.fabric.microsoft.com

認証エラー

問題: Azure CLI で認証が失敗する

解決策:

  • az loginを実行して資格情報を更新する
  • 正しいテナントを確認します。 az account set --subscription <subscription-id>
  • トークンの有効性を確認します。 az account get-access-token --resource https://api.fabric.microsoft.com

クエリ タイムアウト

問題: 大きなテーブルでクエリがタイムアウトする

解決策:

  • ステートメントのタイムアウトを増やす: LivyStatementTimeoutSeconds=300
  • LIMIT句を使用して、開発中に結果のサイズを制限する
  • Spark クラスターに十分なリソースがあることを確認する

セッション作成のタイムアウト

問題: セッションの作成時に接続がタイムアウトする

解決策:

  • セッション タイムアウトを増やす: LivySessionTimeoutSeconds=120
  • Fabric の容量の可用性を確認する
  • ワークスペースがセッション制限に達していないことを確認する

ログ記録を有効にする

問題のトラブルシューティングを行うときに、詳細なログ記録を有効にすると、問題の根本原因を特定するのに役立ちます。 接続文字列を介して、またはプログラムでログ記録を有効にすることができます。

接続文字列を使用して詳細なログ記録を有効にするには:

LogLevel=Debug

または、プログラムで構成します。

using Microsoft.Extensions.Logging;

var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddConsole();
    builder.SetMinimumLevel(LogLevel.Debug);
});

// Logging is automatically integrated with the connection

ログ レベル:

  • Trace: 最も詳細で、すべての API 呼び出しが含まれます
  • Debug: デバッグ情報の詳細
  • Information: 一般的な情報 (既定)
  • Warning: 警告のみ
  • Error: エラーのみ