Microsoft ADO.NET 驅動程式用於 Microsoft Fabric 資料工程

ADO.NET 是 .NET 生態系統中廣泛採用的資料存取技術,使應用程式能夠連接並操作來自資料庫與大數據平台的資料。

Microsoft ADO.NET 驅動程式可用於 Fabric 資料工程,讓您能以標準 ADO.NET 模式的可靠性與簡便性,連接、查詢及管理 Fabric 中的 Spark 工作負載。 該驅動程式建構於 Fabric 的 Livy API 之上,運用熟悉的 DbConnection、DbCommand 和 DbDataReader 抽象,為你的 .NET 應用程式提供安全且靈活的 Spark SQL 連線能力。

關鍵功能

  • ADO.NET API:適用於 Spark SQL 連線的熟悉 DbConnection、DbCommand、DbDataReader、DbParameter 及 DbProviderFactory 抽象
  • Microsoft Entra ID 認證:多重認證流程,包括 Azure CLI、互動式瀏覽器、客戶端憑證、憑證式及存取權杖認證
  • Spark SQL 原生查詢支援:直接執行帶有參數化查詢的 Spark SQL 語句
  • 全面的資料型態支援:支援所有 Spark SQL 資料型態,包括複雜型別(ARRAY、MAP、STRUCT)
  • 連線池:內建連線池管理以提升效能
  • 會話重用:高效的 Spark 會話管理以降低啟動延遲
  • 高並行性會話:選擇共享 Fabric Livy 容量,並以獨立 REPL 來同時租用 HC 會話
  • 非同步預取:背景資料載入以提升大型結果集的效能
  • 自動重新連線:連線失敗後的經典會話恢復;HC 失敗會被顯示出來,供應用程式控制的重試

備註

在開源的 Apache Spark 中,資料庫與結構是同義使用的。 例如,在 Fabric 筆記本中執行 SHOW SCHEMAS 或 SHOW DATABASES 會傳回相同的結果:Lakehouse 中所有結構描述的清單。

先決條件

在使用 Microsoft ADO.NET 驅動程式用於 Fabric 資料工程前,請確保您具備:

  • .NET 執行環境:.NET 8.0 或更新版本
  • Fabric 存取權限:可存取具備資料工程能力的 Fabric 工作空間
  • Azure Entra ID Credentials:適合的驗證憑證
  • 工作區與湖屋 ID:用於 Fabric 工作區與湖屋的 GUID 識別碼
  • Azure CLI (可選):需要用於 Azure CLI 認證方法

下載、包含、參考並驗證

下載 NuGet 套件

這很重要

本文所記載的多值 HcConfOverrides 語法需要 2.0.1 NuGet 套件或更新版本。

在你的專案中參考 NuGet 套件

將下載的 NuGet 套件包含在您的專案中,並對專案檔案加入該套件的參考:

<ItemGroup>
    <PackageReference Include="Microsoft.Spark.Livy.AdoNet" Version="2.0.1" />
</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;" +
    "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 端點。 請指定主機,但不要加上 API 版本後綴。 https://api.fabric.microsoft.com
SparkServerType 伺服器類型識別碼 Fabric
FabricWorkspaceID Microsoft Fabric workspace 識別碼(GUID) 4bbf89a8-66bb-443f-91af-df31e6a7560b
FabricLakehouseID Microsoft Fabric lakehouse identifier(GUID) d8faa650-1343-496b-b9cc-d4168a676f90
AuthFlow 驗證方法 AzureCli、BrowserBased、ClientSecretCredential、ClientCertificateCredential、AuthAccessToken、FileToken

選擇性參數

連線設定

參數 類型 預設值 說明
LivyStatementTimeoutSeconds 整數 600 等待敘述執行所需的時間(秒數)
HttpConnectionTimeoutInSeconds 整數 30 等待 HTTP 連線所需的時間;當用戶端集區中的可用連線已耗盡時,則為等待符合條件的集區連線所需的時間。
SessionName 繩子 (自動) Spark 會話的自訂名稱
EnvironmentID 通用唯一識別碼 (UUID) (無) 適用於經典和 HC 工作階段的可選 Fabric 環境識別碼。
AutoReconnect 布林值 false 啟用經典會話恢復。 在 HC 模式下,過時的 session 失敗會被回傳給應用程式,且不會透明地重播。

連線池設定

參數 類型 預設值 說明
ConnectionPoolEnabled 布林值 true 啟用連線池
MinPoolSize 整數 1 因相容性而被接受,但目前不會強制作為預先配置或維持的集區下限。
MaxPoolSize 整數 50 每個池鍵最多合併的Livy課程次數。
ValidateConnections 布林值 true 在從集區取出工作階段使用時進行遠端驗證。
ValidationTimeoutMs 整數 5000 最大驗證時間以毫秒計。

高併發設定

參數 類型 預設值 說明
HcEnabled 布林值 false 啟用 Fabric Livy 高並發模式。 要求 SparkServerType=Fabric 並路由會話、語句、取消及清理操作,透過 HC 端點進行。
HcSessionTag 繩子 (無) 可選的共享會議打包提示。 如果你省略該值或輸入空值或僅留白的值,驅動程式就不會發送標籤。
HcConfOverrides 繩子 (無) 用於建立 HC 工作階段的、以分號分隔的允許清單中的 Spark 設定覆寫。 當值包含多個覆寫時,請以引號括住完整值。
hcAcquireTimeoutSeconds 整數 300 HC 獲取/會話準備超時時間數為 120..3600 秒。
hcAcquirePollingIntervalMs 整數 1000 HC 取得輪詢間隔,以毫秒為單位(可接受 50..30000,執行階段限制在 100..5000)。

記錄設定

參數 類型 預設值 說明
LogLevel 繩子 Information 日誌層級:Trace,Debug,Information,Warning,Error
LogFilePath 繩子 %LOCALAPPDATA%\FabricSparkAdoNet\Logs 在 Windows 上 檔案式記錄的路徑。

跨驅動程式別名: 驅動程式不僅接受 JDBC 和 ODBC 屬性名稱,還接受原生 ADO.NET 名稱(例如,WorkspaceId 映射到 FabricWorkspaceID,LakehouseId 映射到 FabricLakehouseID)。 所有屬性名稱均不區分大小寫。

範例連接字串

基本連線(Azure CLI 認證)

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

高並行連線

Microsoft Fabric 連線可提供高並行性。 Set HcEnabled=true;標準的 ADO.NET 連線與指令 API 保持不變。 使用不含版本的 Fabric API 主機作為 Server;驅動程式在建置 HC 端點時,預設會使用 FabricVersion=v1 和 LivyApiVersion=2023-12-01。

using Microsoft.Spark.Livy.AdoNet;

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

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

using var command = connection.CreateCommand();
command.CommandText = "SELECT 1 AS value";

object? result = await command.ExecuteScalarAsync();
Console.WriteLine($"Result: {result}");

如需完整的設定指引,請參閱高並行(HC)模式一節。

使用連接池選項

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

具備自動重連及記錄功能

Server=https://api.fabric.microsoft.com;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;" +
    "SparkServerType=Fabric;" +
    "FabricWorkspaceID=<workspace-id>;" +
    "FabricLakehouseID=<lakehouse-id>;" +
    "AuthFlow=AzureCli;";

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

Prerequisites:

  • Azure CLI 安裝: az --version
  • 登入: az login

互動式瀏覽器驗證

最佳應用:面向使用者的應用程式

string connectionString =
    "Server=https://api.fabric.microsoft.com;" +
    "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;" +
    "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 tenant ID
  • AuthClientID:來自 Microsoft Entra ID 的應用程式(用戶端)ID
  • AuthClientSecret:Microsoft Entra ID 的用戶端密碼

憑證式驗證

最佳應用:需要憑證式認證的企業應用

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

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

使用範例

基本連接與查詢

using Microsoft.Spark.Livy.AdoNet;

string connectionString =
    "Server=https://api.fabric.microsoft.com;" +
    "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(rowsAffected >= 0
    ? $"Inserted {rowsAffected} row(s)"
    : "The insert completed, but the driver didn't return an update count.");

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

rowsAffected = await updateCommand.ExecuteNonQueryAsync();
Console.WriteLine(rowsAffected >= 0
    ? $"Updated {rowsAffected} row(s)"
    : "The update completed, but the driver didn't return an update count.");

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

rowsAffected = await deleteCommand.ExecuteNonQueryAsync();
Console.WriteLine(rowsAffected >= 0
    ? $"Deleted {rowsAffected} row(s)"
    : "The delete completed, but the driver didn't return an update count.");

處理大型結果集

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())
{
    int tableNameOrdinal = tablesReader.GetOrdinal("tableName");
    Console.WriteLine($"  {tablesReader.GetString(tableNameOrdinal)}");
}

// 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"]}");
}

// Show databases
using var dbCommand = connection.CreateCommand();
dbCommand.CommandText = "SHOW DATABASES";

using var dbReader = await dbCommand.ExecuteReaderAsync();
Console.WriteLine("\nAvailable databases:");
while (await dbReader.ReadAsync())
{
    Console.WriteLine($"  {dbReader.GetString(0)}");
}

使用 LivyConnectionStringBuilder

using Microsoft.Spark.Livy.AdoNet;

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

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...

高並行(HC)模式

高並行性(HC)模式幫助 .NET 應用程式同時執行 Spark SQL 工作負載,而無需為每個 ADO.NET 連線設定獨立的經典 Spark 會話。 Fabric 可以讓相容的連線共用同一個由伺服器管理的 Livy 工作階段,同時為每個連線提供各自獨立的讀取-評估-輸出迴圈(REPL),以進行陳述式執行。

此模式能縮短連線啟動時間,避免重複配置 Spark 會話,並更有效率地利用 Fabric Spark 容量。 您的應用程式持續使用標準的 ADO.NET API,包括 DbConnection、 DbCommand、 DbDataReaderOpenAsyncClose和 。

HC 模式需主動啟用。 如果你沒有啟用它,驅動程式會使用經典的 Livy 會話路徑。

在 HC 和經典模式之間選擇

以下情況下使用 HC 模式:

  • ASP.NET 服務處理並行請求,開啟連線並執行 Spark SQL。
  • 工作者服務、排程工作或平行資料管線會產生突發性的 ADO.NET 連線。
  • 多個連線連線至相同的 Fabric 工作區和湖屋,並使用相容的 Spark 設定。
  • 減少連線啟動時間及重複配置 Spark 會話非常重要。
  • 你的工作負載可以使用由伺服器管理的共享 Spark 容量,同時透過 REPL 將陳述式執行維持隔離。

當以下情況使用經典模式:

  • 你的應用程式只使用一條或少數幾條長時間維持的連線。
  • 每個連線都需要一個專用的 Spark 工作階段,以實現工作負載或資源的嚴格隔離。
  • 連線需要有相當不同的 Spark 配置,這些配置不應該共享底層會話。
  • 目標工作空間和湖屋的 Fabric Livy 端點不支援 HC 模式。

HC 連結的運作方式

當您的應用程式呼叫 Open 或 OpenAsync,且沒有可用的相容集區連線時,驅動程式:

  1. 向 Fabric 請求一個 HC 會話。
  2. 等待工作階段進入就緒狀態,最長可達設定的取得逾時時間。
  3. 將 ADO.NET 連線連接到指定的 HC 會話及 REPL。
  4. 將指令、查詢、取消要求及清理作業透過 HC 端點傳送。

同時租用的獨立 HC 會話使用不同的 REPL。 同一連線上的指令會共享該連線的 HC 會話和 REPL。

用戶端集區預設為啟用。 關閉或處置符合條件的連線,通常會將其實體 HC 工作階段和 REPL 返回程序本機集區以供重複使用;但不一定會在遠端釋放該指派關係。 停用連線集區時,關閉實體連線會執行 HC 清理。 繼續使用 using 陳述式,讓邏輯連結能迅速回傳。

啟用 HC 模式

HC 模式需由使用者主動啟用。 如果你省略 hcEnabled 或設為 false,驅動程式會使用經典的 Livy 會話路徑。

將屬性 hcEnabled 設為 true,以取得 HC 會話:

hcEnabled=true;

這很重要

  1. 對於 HC 連線,請使用未封版本的 Fabric API 主機。Server 驅動程式在建置 HC 端點時,會套用預設的 Fabric 和 Livy API 版本。
  2. 房產名稱不區分大小寫。

設定會話打包

HcSessionTag 提供伺服器端提示,以便將相容的 HC 工作階段整併至底層的 Livy 工作階段中。 匹配的標籤並不保證會放在相同的底層會話中。

如果您省略該標記,或提供空值或僅包含空白字元的值,驅動程式就不會在 acquire 要求中傳送它。 省略該標籤並不會停用 HC 模式或伺服器端封裝。 當相關的應用程式實例或工作負載應被納入共享容量時,明確設定標籤。 使用穩定且不敏感的操作標籤,例如 reporting-service 或 nightly-etl。 不要包含機密、存取權杖、個人資料、客戶識別碼或查詢文字。

Spark 設定也會影響會話相容性。 用 HcConfOverrides 來提供 Allowlist 的 Spark 設定以建立 HC 會話:

Server=https://api.fabric.microsoft.com;SparkServerType=Fabric;AuthFlow=AzureCli;HcEnabled=true;HcConfOverrides="spark.executor.memory=8g;spark.executor.cores=4";

有多個覆寫項目時,請將整個 HcConfOverrides 值加上引號。 未加引號的分號會開始另一個外部連線字串屬性;它不會延伸到 HcConfOverrides。 解析器接受單引號或雙引號值,保留引號與等號,並解碼雙引號'' (或 "")。 屬性名稱周圍以及未加引號的值外側邊緣的空白會被忽略。 未引號值內的空白位及引號值內的所有空白位均被保留。 空值會覆蓋環境預設值,最後重複的屬性勝出。

你也可以讓 LivyConnectionStringBuilder 自己處理引用:

var builder = new Microsoft.Spark.Livy.AdoNet.LivyConnectionStringBuilder
{
    Server = "https://api.fabric.microsoft.com",
    SparkServerType = "Fabric",
    FabricWorkspaceID = "<workspace-id>",
    FabricLakehouseID = "<lakehouse-id>",
    AuthFlow = "AzureCli",
    HcEnabled = true,
    HcConfOverrides = "spark.executor.memory=8g;spark.executor.cores=4"
};

string connectionString = builder.ConnectionString;

這些範例需要 Microsoft ADO.NET 驅動程式版本 2.0.1 或更新版本。 在開啟連線前,先加入你的工作空間和湖屋識別碼。 這兩個覆寫都是在 HC 建立會話請求中作為獨立 conf 條目發送的。 每個覆寫必須使用以下以下區分大小寫的鍵之一:

  • spark.sql.shuffle.partitions
  • spark.executor.memory
  • spark.executor.cores
  • spark.driver.memory
  • spark.sql.ansi.enabled
  • spark.sql.legacy.timeParserPolicy
  • spark.sql.session.timeZone
  • livy.rsc.client.connect.timeout
  • livy.rsc.server.idle-timeout

格式錯誤的引號會遭到拒絕,且剖析錯誤訊息中不會包含連線字串內容。

在旨在共享容量的連線間使用一致的標籤和設定值。 Fabric 判斷請求是否能使用現有會話,或需要另一個會話。

設定擷取時序

請使用以下設定來控制駕駛等待 HC 會話的時間長短:

參數 預設值 有效的輸入 行為
hcAcquireTimeoutSeconds 300 120 到 3,600 秒 等待HC會議準備好的最長時間。
hcAcquirePollingIntervalMs 1000 50到30,000毫秒 狀態檢查間隔。 執行時,驅動程式會將數值限制在 100 到 5,000 毫秒之間。

對於大多數工作負載,請維持預設值。 只有當容量啟動經常超過五分鐘時,才應延長採購逾時。

使用帶有連線池的 HC 模式

HC 模式與 ADO.NET 連線池處理不同層級:

  • HC 模式管理伺服器上的共享 Fabric Spark 容量與 Livy 會話。
  • ADO.NET 連線池在用戶端應用程式中重用驅動程式管理的連線資源。

你可以啟用這兩個功能。 連線池減少了重複的用戶端連線設定,而 HC 模式則減少了伺服器端重複的 Spark 會話配置。 根據應用程式預期的並行性來調整連線池大小,而不是用一個大池來產生不必要的平行運算。

在 HC 模式下,AutoReconnect=true 不會在發生工作階段過期錯誤後自動重新執行失敗的命令。 應用程式會收到例外,並必須決定重試操作是否安全。

關閉 HC 模式

若要對新連線使用經典模式,請從連線字串中移除 HcEnabled,或將其設為 false:

HcEnabled=false

這項變更會影響新連線,且不會清除現有的合併 HC 會話。 正常關閉或釋放邏輯連線;符合條件的實體工作階段可保留在用戶端集區中,直到淘汰為止。

ADO.NET 限制

  • 交易不被支援。
  • 指令僅支援文字指令模式。 不支援預存程序命令模式和資料表直接命令模式。
  • Prepare 不執行任何動作。
  • 指令必須包含一個語句;多語句的指令文字會被拒絕。
  • 同時使用獨立且同時開啟的連線來處理並行工作負載。 同一連線上的指令會共享其會話和 REPL。

數據類型映射

驅動程式將 Spark SQL 資料型態映射到 .NET 類型:

Spark SQL 類型 .NET 型別 DbType
BOOLEAN bool 布林值
TINYINT sbyte SByte
斯莫林特 short Int16
INT int Int32
BIGINT long Int64
FLOAT float Single
雙倍 double Double
小數(p, s) decimal 十進制
STRING string 繩子
VARCHAR(n) string 繩子
CHAR(n) string 繩子
BINARY byte[] Binary
DATE DateTime 日期
TIMESTAMP DateTime 日期時間
陣列<T> string 物件
地圖<K,V> string 物件
STRUCT string 物件

處理複雜型態

HC 的結果路徑不會可靠地將原生巢狀的 ARRAY、MAP 或 STRUCT 值序列化成 JSON。 在 Spark SQL 中,先將複雜值轉換為 JSON 字串,再將其反序列化:

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

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

using var reader = await command.ExecuteReaderAsync();
if (await reader.ReadAsync())
{
    string arrayJson = reader.GetString(0);
    string mapJson = reader.GetString(1);
    string structJson = reader.GetString(2);

    var array = JsonSerializer.Deserialize<int[]>(arrayJson);
    var map = JsonSerializer.Deserialize<Dictionary<string, string>>(mapJson);
}

Troubleshooting

本節提供解決您在使用 Microsoft ADO.NET 驅動程式 for Fabric Data Engineering 時可能遇到的常見問題的指引。

常見問題

以下章節說明常見問題及其解決方案:

連線失敗

問題:無法連接 Fabric

解決方案:

  1. 驗證 FabricWorkspaceID 和 FabricLakehouseID 是否為正確的 GUIDs
  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=1200。
  • 在開發過程中使用 LIMIT 條款限制結果大小
  • 確保 Spark 集群擁有足夠資源

連線或 HC 獲取超時

問題:等待連線集區中的連線或 HC 工作階段時,連線逾時

解決方案:

  • 如需了解用戶端集區等待和 HTTP 連線建立,請參閱 HttpConnectionTimeoutInSeconds。
  • 在 HC 擷取時,請將 hcAcquireTimeoutSeconds 增加至支援的 120 到 3,600 秒範圍內。
  • 檢查 Fabric 容量可用性
  • 確認工作空間沒有達到會話限制

啟用日誌記錄

在排除問題時,詳細的日誌記錄可以幫助你找出根本原因。 透過連線字串設定記錄:

為了透過連接字串實現詳細記錄:

LogLevel=Debug;LogFilePath=<path-to-log-file>

如果您沒有設定 LogFilePath 或全域記錄組態,驅動程式會在 Windows 上將日誌寫入 %LOCALAPPDATA%\FabricSparkAdoNet\Logs。

日誌等級:

  • Trace: 最冗長,包含所有 API 呼叫
  • Debug: 詳細除錯資訊
  • Information:一般資訊(預設)
  • Warning:僅顯示警告
  • Error:僅有錯誤