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 套件
- 下載 Microsoft ADO.NET 驅動程式用於 Fabric Data Engineering(zip)
- 下載適用於 Fabric Data Engineering 的 Microsoft ADO.NET 驅動程式 (tar)
這很重要
本文所記載的多值 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,且沒有可用的相容集區連線時,驅動程式:
- 向 Fabric 請求一個 HC 會話。
- 等待工作階段進入就緒狀態,最長可達設定的取得逾時時間。
- 將 ADO.NET 連線連接到指定的 HC 會話及 REPL。
- 將指令、查詢、取消要求及清理作業透過 HC 端點傳送。
同時租用的獨立 HC 會話使用不同的 REPL。 同一連線上的指令會共享該連線的 HC 會話和 REPL。
用戶端集區預設為啟用。 關閉或處置符合條件的連線,通常會將其實體 HC 工作階段和 REPL 返回程序本機集區以供重複使用;但不一定會在遠端釋放該指派關係。 停用連線集區時,關閉實體連線會執行 HC 清理。 繼續使用 using 陳述式,讓邏輯連結能迅速回傳。
啟用 HC 模式
HC 模式需由使用者主動啟用。 如果你省略 hcEnabled 或設為 false,驅動程式會使用經典的 Livy 會話路徑。
將屬性 hcEnabled 設為 true,以取得 HC 會話:
hcEnabled=true;
這很重要
- 對於 HC 連線,請使用未封版本的 Fabric API 主機。
Server驅動程式在建置 HC 端點時,會套用預設的 Fabric 和 Livy API 版本。 - 房產名稱不區分大小寫。
設定會話打包
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.partitionsspark.executor.memoryspark.executor.coresspark.driver.memoryspark.sql.ansi.enabledspark.sql.legacy.timeParserPolicyspark.sql.session.timeZonelivy.rsc.client.connect.timeoutlivy.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
解決方案:
- 驗證
FabricWorkspaceID和FabricLakehouseID是否為正確的 GUIDs - 檢查 Azure CLI 認證:
az account show - 確保你擁有適當的 Fabric 工作區權限
- 驗證到
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:僅有錯誤