Driver ADO.NET di Microsoft per Microsoft Fabric Data Engineering (Anteprima)

Importante

Questa funzionalità si trova in Anteprima.

ADO.NET è una tecnologia di accesso ai dati ampiamente adottata nell'ecosistema .NET che consente alle applicazioni di connettersi e lavorare con i dati dai database e dalle piattaforme Big Data.

Microsoft ADO.NET Driver for Fabric Data Engineering consente di connettere, eseguire query e gestire carichi di lavoro Spark in Microsoft Fabric con affidabilità e semplicità dei modelli di ADO.NET standard. Basato sulle API Livy di Microsoft Fabric, il driver offre una connettività Spark SQL sicura e flessibile alle applicazioni .NET utilizzando astrazioni familiari DbConnection, DbCommand e DbDataReader.

Funzionalità principali

  • ADO.NET Conforme: implementazione completa di astrazioni ADO.NET (DbConnection, DbCommand, DbDataReader, DbParameter, DbProviderFactory)
  • Autenticazione ID Microsoft Entra: più flussi di autenticazione, tra cui l'interfaccia della riga di comando di Azure, browser interattivo, credenziali client, autenticazione basata su certificati e token di accesso
  • Supporto per query nativo Spark SQL: Esecuzione diretta di istruzioni Spark SQL con query parametrizzate
  • Supporto completo dei tipi di dati: supporto per tutti i tipi di dati SPARK SQL, inclusi tipi complessi (ARRAY, MAP, STRUCT)
  • Pool di connessioni: gestione predefinita del pool di connessioni per migliorare le prestazioni
  • Riutilizzo sessione: gestione efficiente delle sessioni Spark per ridurre la latenza di avvio
  • Prelettura asincrona: caricamento dei dati in background per prestazioni migliorate con set di risultati di grandi dimensioni
  • Riconnessione automatica: ripristino automatico della sessione dopo gli errori di connessione

Annotazioni

In Apache Spark open source, il database e lo schema vengono usati come sinonimi. Ad esempio, l'esecuzione di SHOW SCHEMAS o SHOW DATABASES in un notebook di Fabric restituisce lo stesso risultato, ovvero un elenco di tutti gli schemi in Lakehouse.

Prerequisiti

Prima di usare Microsoft ADO.NET Driver for Microsoft Fabric Data Engineering, assicurarsi di disporre di:

  • Runtime .NET: .NET 8.0 o versione successiva
  • Microsoft Fabric Access: accesso a un'area di lavoro di Microsoft Fabric con funzionalità di ingegneria dei dati
  • Azure Entra ID Credentials: credenziali appropriate per l'autenticazione
  • ID area di lavoro e Lakehouse: identificatori GUID per il tuo workspace e lakehouse Fabric
  • Interfaccia della riga di comando di Azure (facoltativo): obbligatorio per il metodo di autenticazione dell'interfaccia della riga di comando di Azure

Scaricare, includere, fare riferimento e verificare

Scaricare il pacchetto NuGet

Microsoft ADO.NET Driver for Microsoft Fabric Data Engineering versione 1.0.0 è disponibile in anteprima pubblica che è possibile scaricare da questi collegamenti all'Area download.

Fare riferimento al pacchetto NuGet nel progetto

Includere il pacchetto NuGet scaricato nel progetto e aggiungere un riferimento del pacchetto al file di progetto:

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

Verifica l'installazione

Dopo l'inclusione e il riferimento, verificare che il pacchetto sia disponibile nel progetto:

using Microsoft.Spark.Livy.AdoNet;

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

Esempio di avvio rapido

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));
}

Formato della stringa di connessione

Formato di base

Microsoft ADO.NET Driver usa il formato della stringa di connessione standard ADO.NET:

Parameter1=Value1;Parameter2=Value2;...

Parametri obbligatori

Parametro Descrizione Esempio
Server Endpoint dell'API Di Microsoft Fabric https://api.fabric.microsoft.com/v1
SparkServerType Identificatore del tipo di server Fabric
FabricWorkspaceID Identificatore dell'area di lavoro di Microsoft Fabric (GUID) <workspace-id>
FabricLakehouseID Identificatore Microsoft Fabric lakehouse (GUID) <lakehouse-id>
AuthFlow Metodo di autenticazione AzureCli, BrowserBased, ClientSecretCredential, ClientCertificateCredential, AuthAccessTokenFileToken

Parametri facoltativi

Impostazioni di connessione

Parametro Tipo Impostazione predefinita Descrizione
LivySessionTimeoutSeconds Integer 60 Tempo in secondi per attendere la creazione della sessione
LivyStatementTimeoutSeconds Integer 600 Tempo in secondi per attendere l'esecuzione dell'istruzione
SessionName string (automatica) Nome personalizzato per la sessione spark
AutoReconnect Booleano false Abilitare il ripristino automatico della sessione

Impostazioni del pool di connessioni

Parametro Tipo Impostazione predefinita Descrizione
ConnectionPoolEnabled Booleano true Abilitare il pool di connessioni
MinPoolSize Integer 1 Connessioni minime nel pool
MaxPoolSize Integer 20 Numero massimo di connessioni nel pool
ConnectionMaxIdleTimeMs Integer 1800000 Tempo di inattività massimo prima del riciclo della connessione (30 minuti)
MaxLifetimeMs Integer 3600000 Durata massima di una connessione del pool (60 minuti)
ValidateConnections Booleano true Convalidare le connessioni prima dell'uso
ValidationTimeoutMs Integer 5000 Timeout per la convalida della connessione

Impostazioni di registrazione

Parametro Tipo Impostazione predefinita Descrizione
LogLevel string Information Livello di log: Trace, Debug, Information, Warning, Error
LogFilePath string (nessuno) Percorso per la registrazione basata su file

Annotazioni

Alias tra driver: Il driver accetta nomi di proprietà JDBC e ODBC oltre a nomi nativi ADO.NET (ad esempio, WorkspaceId viene mappato su FabricWorkspaceID, LakehouseId viene mappato su FabricLakehouseID). Tutti i nomi delle proprietà sono insensibili alla distinzione tra maiuscole e minuscole.

Esempi di stringhe di connessione

Connessione di base (autenticazione dell'interfaccia della riga di comando di Azure)

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

Con le opzioni di pool di connessioni

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

Con la riconnessione automatica e la registrazione

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

Autenticazione

Microsoft ADO.NET Driver supporta più metodi di autenticazione tramite Microsoft Entra ID (in precedenza Azure Active Directory). L'autenticazione viene configurata usando il AuthFlow parametro nella stringa di connessione.

Metodi di autenticazione

Valore AuthFlow Descrizione Ideale per
AzureCli Usa le credenziali memorizzate nella cache dell'interfaccia della riga di comando di Azure Sviluppo e test
BrowserBased Autenticazione interattiva basata su browser Applicazioni rivolte agli utenti
ClientSecretCredential Principale del servizio con segreto del client Servizi automatizzati, attività in background
ClientCertificateCredential Principale del servizio con certificato Applicazioni aziendali
AuthAccessToken Token di accesso a portatore pre-acquisito Scenari di autenticazione personalizzati

Autenticazione dell’Azure CLI

Ideale per: sviluppo e test

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();

Prerequisites:

  • Interfaccia della riga di comando di Azure installata: az --version
  • Autenticato: az login

Autenticazione interattiva del browser

Ideale per: applicazioni rivolte agli utenti

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

Comportamento:

  • Apre una finestra del browser per l'autenticazione utente
  • Le credenziali vengono memorizzate nella cache per le connessioni successive

Autenticazione delle credenziali client (principale del servizio)

Ideale per: servizi automatizzati e processi in background

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();

Parametri obbligatori:

  • AuthTenantID: ID tenant di Azure
  • AuthClientID: ID dell'applicazione (client) di Microsoft Entra ID
  • AuthClientSecret: segreto del client da Microsoft Entra ID

Autenticazione basata su certificati

Ideale per: applicazioni aziendali che richiedono l'autenticazione basata su certificati

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();

Parametri obbligatori:

  • AuthTenantID: ID tenant di Azure
  • AuthClientID: ID applicazione (cliente)
  • AuthCertificatePath: percorso del file di certificato PFX/PKCS12
  • AuthCertificatePassword: password del certificato

Autenticazione del token di accesso

Ideale per: scenari di autenticazione personalizzati

// 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();

Annotazioni

È consigliabile evitare credenziali hardcoded, ad esempio password, chiavi, segreti, token o certificati nel codice. Usare invece Azure Key Vault per archiviare in modo sicuro questi valori e recuperarli in fase di esecuzione.

Esempi di utilizzo

Query e connessione di base

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();
}

Query con parametri

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 per valori unici

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

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

ExecuteNonQuery per le operazioni DML

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

Utilizzo di set di risultati di grandi dimensioni

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

Rilevazione dello schema

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

Uso di 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();

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

Mappatura del tipo di dati

Il driver esegue il mapping dei tipi di dati Spark SQL ai tipi .NET:

Tipo SQL Spark Tipo di .NET DbType (Tipo di database)
BOOLEAN bool Booleano
TINYINT sbyte SByte
SMALLINT short Int16
INT int Int32
BIGINT long Int64
FLOAT float Single
DOPPIO double Double
DECIMAL(p,s) decimal Decimale
filo string string
VARCHAR(n) string string
CHAR(n) string string
BINARY byte[] Binario
DATTERO DateTime Date
TIMESTAMP DateTime DateTime
MATRICE<T> T[] o string (JSON) oggetto
MAP<K,V> Dictionary<K,V> o string (JSON) oggetto
STRUCT object o string (JSON) oggetto

Lavorare con tipi complessi

I tipi complessi (ARRAY, MAP, STRUCT) vengono restituiti come stringhe JSON per impostazione predefinita:

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);
}

Risoluzione dei problemi

Questa sezione fornisce indicazioni per la risoluzione dei problemi comuni che possono verificarsi quando si usa Microsoft ADO.NET Driver per Microsoft Fabric Data Engineering.

Problemi comuni

Le sezioni seguenti descrivono i problemi comuni e le relative soluzioni:

Errori di connessione

Problema: Non è possibile connettersi a Microsoft Fabric

Soluzioni:

  1. Verificare che FabricWorkspaceID e FabricLakehouseID siano GUID corretti
  2. Controllare l'autenticazione della CLI di Azure: az account show
  3. Assicurati di possedere le autorizzazioni appropriate per l'area di lavoro Fabric.
  4. Verificare la connettività di rete a api.fabric.microsoft.com

Errori di autenticazione

Problema: l'autenticazione non riesce con l'interfaccia della riga di comando di Azure

Soluzioni:

  • Eseguire az login per aggiornare le credenziali
  • Verificare il tenant corretto: az account set --subscription <subscription-id>
  • Controllare la validità del token: az account get-access-token --resource https://api.fabric.microsoft.com

Timeout query

Problema: timeout delle query su tabelle di grandi dimensioni

Soluzioni:

  • Aumentare il timeout dell'istruzione: LivyStatementTimeoutSeconds=300
  • Utilizzare la clausola LIMIT per limitare le dimensioni dei risultati durante lo sviluppo
  • Verificare che il cluster Spark disponga di risorse adeguate

Timeout di creazione della sessione

Problema: Timeout della connessione durante la creazione della sessione

Soluzioni:

  • Aumentare il timeout della sessione: LivySessionTimeoutSeconds=120
  • Controllare la disponibilità della capacità del Fabric
  • Verificare che l'area di lavoro non abbia raggiunto i limiti di sessione

Abilitare la registrazione

Durante la risoluzione dei problemi, l'abilitazione della registrazione dettagliata consente di identificare la causa radice dei problemi. È possibile abilitare la registrazione tramite la stringa di connessione o a livello di codice.

Per abilitare la registrazione dettagliata tramite la stringa di connessione:

LogLevel=Debug

Oppure configurare a livello di codice:

using Microsoft.Extensions.Logging;

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

// Logging is automatically integrated with the connection

Livelli di log:

  • Trace: livello di massima verbosità, include tutte le chiamate API
  • Debug: informazioni dettagliate sul debug
  • Information: informazioni generali (impostazione predefinita)
  • Warning: Solo avvertimenti
  • Error: solo errori