Driver Microsoft ADO.NET para Microsoft Fabric Data Engineering

ADO.NET é uma tecnologia de acesso a dados amplamente adotada no ecossistema do .NET que permite que os aplicativos se conectem e trabalhem com dados de bancos de dados e plataformas de Big Data.

O driver Microsoft ADO.NET para Fabric Data Engineering permite que você conecte, consulte e gerencie cargas de trabalho do Spark no Fabric com a confiabilidade e simplicidade dos padrões padrão ADO.NET. Baseado nas APIs Livy do Fabric, o driver oferece conectividade segura e flexível ao Spark SQL para suas aplicações .NET usando abstrações familiares DbConnection, DbCommand e DbDataReader.

Características principais

  • APIs ADO.NET: Familiares DbConnection, DbCommand, DbDataReader, DbParameter, e DbProviderFactory abstrações para conectividade SQL do Spark
  • Autenticação de Identidade do Microsoft Entra: múltiplos fluxos de autenticação incluindo CLI do Azure, navegador interativo, credenciais de cliente, baseada em certificado e autenticação de token de acesso.
  • Suporte à consulta nativa do Spark SQL: execução direta de instruções SQL do Spark com consultas parametrizadas
  • Suporte a tipos de dados abrangentes: suporte para todos os tipos de dados SQL do Spark, incluindo tipos complexos (ARRAY, MAP, STRUCT)
  • Agrupamento de Conexões: gerenciamento interno do pool de conexões para melhorar o desempenho
  • Reutilização da sessão: gerenciamento eficiente de sessão do Spark para reduzir a latência de inicialização
  • Sessões de alta concorrência: Opte pela capacidade compartilhada do Fabric Livy com REPLs separados para sessões HC alugadas simultaneamente
  • Pré-busca assíncrona: carregamento de dados em segundo plano para melhorar o desempenho com grandes conjuntos de resultados
  • Reconexão automática: Recuperação da sessão clássica após falhas de conexão; falhas HC são expostas para nova tentativa controlada pela aplicação

Observação

No Apache Spark de software livre, o banco de dados e o esquema são usados sinônimos. Por exemplo, executar SHOW SCHEMAS ou SHOW DATABASES em um notebook do Fabric retorna o mesmo resultado — uma lista de todos os esquemas no lakehouse.

Pré-requisitos

Antes de usar o driver Microsoft ADO.NET para Fabric Data Engineering, certifique-se de que você possui:

  • Runtime do .NET: .NET 8.0 ou posterior
  • Fabric Access: Acesso a um espaço de trabalho Fabric com capacidades de Engenharia de Dados
  • Credenciais de ID do Azure Entra: credenciais apropriadas para autenticação
  • IDs do Workspace e Lakehouse: identificadores GUID para o seu Workspace do Fabric e Lakehouse
  • CLI do Azure (opcional): necessário para o método de autenticação da CLI do Azure

Baixar, incluir, fazer referência e verificar

Baixar o pacote NuGet

Importante

A sintaxe multi-valor HcConfOverrides citada documentada neste artigo requer o pacote NuGet 2.0.1 ou posterior.

Fazer referência ao pacote NuGet em seu projeto

Inclua o pacote NuGet baixado em seu projeto e adicione uma referência do pacote ao arquivo de projeto:

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

Verifique a instalação

Após a inclusão e a referência, verifique se o pacote está disponível em seu projeto:

using Microsoft.Spark.Livy.AdoNet;

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

Exemplo de início rápido

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

Formato da cadeia de conexão

Formato básico

O Microsoft ADO.NET Driver usa o formato de cadeia de conexão de ADO.NET padrão:

Parameter1=Value1;Parameter2=Value2;...

Parâmetros necessários

Parâmetro Descrição Exemplo
Server Endpoint da API do Microsoft Fabric. Especifique o host sem um sufixo de versão da API. https://api.fabric.microsoft.com
SparkServerType Identificador de tipo de servidor Fabric
FabricWorkspaceID Identificador de workspace do Microsoft Fabric (GUID) 4bbf89a8-66bb-443f-91af-df31e6a7560b
FabricLakehouseID Identificador do Microsoft Fabric Lakehouse (GUID) d8faa650-1343-496b-b9cc-d4168a676f90
AuthFlow Método de autenticação AzureCli, BrowserBased, ClientSecretCredential, ClientCertificateCredential, AuthAccessToken, , FileToken

Parâmetros opcionais

Configurações de conexão

Parâmetro Tipo Default Descrição
LivyStatementTimeoutSeconds Integer 600 Tempo em segundos para aguardar a execução do comando
HttpConnectionTimeoutInSeconds Integer 30 É hora de esperar por uma conexão HTTP e, quando o pool de clientes se esgota, por uma conexão pooled elegível.
SessionName String (auto) Nome personalizado para a sessão do Spark
EnvironmentID Identificador Único Universal (UUID) (nenhuma) Identificador opcional de ambiente do Fabric para sessões clássicas e HC.
AutoReconnect booleano false Ative a recuperação da sessão no modo clássico. No modo HC, uma falha de sessão estagnada é devolvida à aplicação e não é reproduzida de forma transparente.

Configurações do pool de conexões

Parâmetro Tipo Default Descrição
ConnectionPoolEnabled booleano true Habilitar o pool de conexões
MinPoolSize Integer 1 Aceito para compatibilidade, mas atualmente não é aplicado como um pool mínimo pré-alocado ou mantido.
MaxPoolSize Integer 50 Número máximo de sessões Livy agrupadas por chave do pool.
ValidateConnections booleano true Valide sessões agrupadas remotamente quando forem prestadas em check-out.
ValidationTimeoutMs Integer 5000 Duração máxima de validação em milissegundos.

Configurações de alta concorrência

Parâmetro Tipo Default Descrição
HcEnabled booleano false Ative o modo de Concorrência Fabric Livy High. Requer SparkServerType=Fabric e roteia operações de sessão, instrução, cancelamento e limpeza por meio de endpoints de HC.
HcSessionTag String (nenhuma) Dica opcional de empacotamento para sessão compartilhada. Se você omitir o valor ou inserir um valor vazio ou apenas de espaço em branco, o motorista não envia uma etiqueta.
HcConfOverrides String (nenhuma) Overrides de configuração permitida do Spark delimitadas por ponto e vírgula para criação de sessões HC. Declare o valor total quando ele contiver múltiplas sobrescrições.
hcAcquireTimeoutSeconds Integer 300 Tempo limite do HC para aquisição/sessão pronta, em segundos (120..3600).
hcAcquirePollingIntervalMs Integer 1000 HC adquire intervalo de sondagem em milissegundos (50..30.000 aceitos, runtime clamp 100..5000).

Configurações de registro em log

Parâmetro Tipo Default Descrição
LogLevel String Information Nível de log: Trace, Debug, Information, Warning, Error
LogFilePath String %LOCALAPPDATA%\FabricSparkAdoNet\Logs no Windows Caminho para registro baseado em arquivos.

Aliases entre drivers: O driver aceita nomes de propriedade JDBC e ODBC, além de nomes de ADO.NET nativos (por exemplo, WorkspaceId mapeia para FabricWorkspaceID, mapeia LakehouseId para FabricLakehouseID). Todos os nomes de propriedade não diferenciam maiúsculas de minúsculas.

Cadeias de conexão de exemplo

Conexão básica (autenticação da CLI do Azure)

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

Conexão de alta simultaneidade

Alta concorrência está disponível para conexões Microsoft Fabric. Defina HcEnabled=true; as APIs padrão de conexão e comando ADO.NET permanecem inalteradas. Use o host da API Fabric sem versão para Server; o driver usa FabricVersion=v1 e LivyApiVersion=2023-12-01 por padrão ao montar o endpoint HC.

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

Para obter orientações completas sobre a configuração, consulte a seção modo de alta concorrência (HC).

Com opções de pool de conexões

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

Com reconexão automática e registro em log

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

Autenticação

O Microsoft ADO.NET Driver dá suporte a vários métodos de autenticação por meio da ID do Microsoft Entra (antigo Azure Active Directory). A autenticação é configurada usando o AuthFlow parâmetro na cadeia de conexão.

Métodos de autenticação

Valor do AuthFlow Descrição Mais Adequado Para
AzureCli Usa credenciais armazenadas em cache da CLI do Azure Desenvolvimento e teste
BrowserBased Autenticação interativa baseada em navegador Aplicativos voltados para o usuário
ClientSecretCredential Entidade de serviço com segredo do cliente Serviços automatizados, trabalhos em segundo plano
ClientCertificateCredential Principal de serviço com certificado Aplicativos empresariais
AuthAccessToken Token de acesso do portador pré-adquirido Cenários de autenticação personalizados

Autenticação da CLI do Azure

Melhor para: Desenvolvimento e teste

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

Pré-requisitos:

  • CLI do Azure instalada: az --version
  • Conectado: az login

Autenticação interativa do navegador

Melhor para: aplicativos voltados para o usuário

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

Comportamento:

  • Abre uma janela do navegador para autenticação do usuário
  • As credenciais são armazenadas em cache para conexões subsequentes

Autenticação de Credenciais de Cliente (Principal do Serviço)

Melhor para: serviços automatizados e trabalhos em segundo plano

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

Parâmetros necessários:

  • AuthTenantID: ID do locatário do Azure
  • AuthClientID: ID do aplicativo (cliente) da Microsoft Entra ID
  • AuthClientSecret: segredo do cliente do Microsoft Entra ID

Autenticação baseada em certificado

Melhor para: aplicativos empresariais que exigem autenticação baseada em certificado

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

Parâmetros necessários:

  • AuthTenantID: ID do locatário do Azure
  • AuthClientID: ID do aplicativo (cliente)
  • AuthCertificatePath: caminho para o arquivo de certificado PFX/PKCS12
  • AuthCertificatePassword: senha do certificado

Autenticação de token de acesso

Melhor para: cenários de autenticação personalizados

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

Exemplos de uso

Conexão e consulta básicas

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

Consultas parametrizadas

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 para valores únicos

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

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

ExecuteNonQuery para as operações 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(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.");

Trabalhando com grandes conjuntos de resultados

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

Descoberta de esquema

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

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

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

Modo de alta concorrência (HC)

O modo de alta concorrência (HC) ajuda aplicações .NET a executar cargas de trabalho SQL Spark concorrentes sem precisar de provisionar uma sessão clássica separada do Spark para cada conexão ADO.NET. O Fabric pode colocar conexões compatíveis na mesma sessão Livy gerenciada pelo servidor, fornecendo a cada conexão um loop de leitura, avaliação e impressão (REPL) isolado para a execução de instruções.

Esse modelo pode reduzir o tempo de inicialização da conexão, evitar o provisionamento repetido de sessões do Spark e usar a capacidade do Fabric Spark de forma mais eficiente. Sua aplicação continua a usar APIs padrão do ADO.NET, incluindo DbConnection, DbCommand, DbDataReader, OpenAsync, e Close.

O modo HC é opcional. Se você não ativar isso, o driver usa o caminho clássico de sessão do Livy.

Escolha entre HC e modo clássico

Use o modo HC quando:

  • Um serviço ASP.NET lida com requisições concorrentes que abrem conexões e executam Spark SQL.
  • Um serviço de trabalho, trabalho agendado ou pipeline de dados paralelo cria rajadas de conexões ADO.NET.
  • Múltiplas conexões visam o mesmo espaço de trabalho Fabric e a mesma casa do lago e usam configurações compatíveis com o Spark.
  • Reduzir o tempo de inicialização da conexão e o provisionamento repetido das sessões do Spark é importante.
  • Sua carga de trabalho pode usar capacidade compartilhada e gerenciada pelo servidor do Spark, mantendo a execução de instruções isolada pelo REPL.

Use o modo clássico quando:

  • Sua aplicação utiliza apenas uma ou poucas conexões duradouras.
  • Cada conexão requer uma sessão dedicada do Spark para carga de trabalho rigorosa ou isolamento de recursos.
  • Conexões exigem configurações substancialmente diferentes do Spark que não deveriam compartilhar uma sessão subjacente.
  • O endpoint do Fabric Livy para o workspace de destino e o lakehouse não é compatível com o modo HC.

Como funcionam as conexões HC

Quando sua aplicação chama Open ou OpenAsync e nenhuma conexão em pool compatível está disponível, o driver:

  1. Solicita uma sessão HC do Fabric.
  2. Espera até que a sessão esteja pronta, até o tempo limite de aquisição configurado.
  3. Conecta a conexão ADO.NET à sessão HC atribuída e ao REPL.
  4. Encaminha comandos, consultas, solicitações de cancelamento e operações de limpeza por meio dos endpoints HC.

Sessões HC separadas e alugadas simultaneamente usam REPLs separados. Comandos em uma conexão compartilham a sessão HC e o REPL dessa conexão.

O pooling no cliente é ativado por padrão. Fechar ou descartar uma conexão elegível normalmente retorna sua sessão HC física e o REPL para o pool local do processo para reutilização; isso não necessariamente libera a atribuição remotamente. Com o pooling desativado, fechar a conexão física realiza a limpeza HC. Continue usando using instruções para que as conexões lógicas retornem rapidamente.

Ativar o modo HC

O modo HC é opcional. Se você omitir hcEnabled ou defini-lo como false, o driver usará o caminho clássico de sessão do Livy.

Defina a propriedade hcEnabled como verdadeiro para obter uma sessão HC:

hcEnabled=true;

Importante

  1. Para conexões HC, use o host API Fabric não versionado para Server. O driver aplica as versões padrão da API Fabric e Livy ao construir o endpoint HC.
  2. Nomes de propriedades não são diferenciados em maiúsculas e minúsculas.

Configurar o pacote de sessão

HcSessionTag fornece uma dica do lado do servidor para empacotar sessões HC compatíveis em uma sessão Livy subjacente. Uma tag correspondente não garante a colocação na mesma sessão subjacente.

Se você omitir a tag ou fornecer um valor vazio ou composto apenas por espaços em branco, o driver não a envia na requisição de aquisição. Omitir a tag não desativa o modo HC nem o empacotamento no lado do serviço. Defina uma tag explícita quando instâncias ou cargas de trabalho relacionadas devem ser consideradas para capacidade compartilhada. Use um rótulo operacional estável e não sensível, como reporting-service ou nightly-etl. Não inclua segredos, tokens de acesso, dados pessoais, identificadores de clientes ou texto de consulta.

A configuração do Spark também afeta a compatibilidade da sessão. Use HcConfOverrides para fornecer configurações do Spark incluídas na lista de permissões para a criação de sessões do HC:

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

Para múltiplas substituições, coloque todo o valor HcConfOverrides entre aspas. Um ponto e vírgula sem aspas inicia outra propriedade externa da cadeia de conexão; ele não amplia HcConfOverrides. O analisador aceita valores entre aspas simples ou duplas, preserva pontos e vírgulas e sinais de igual dentro de valores entre aspas e decodifica aspas correspondentes duplicadas ('' ou ""). Espaços em branco ao redor dos nomes das propriedades e nas extremidades externas dos valores sem aspas são ignorados. Os espaços em branco dentro dos valores sem aspas e todos os espaços em branco dentro dos valores entre aspas são preservados. Valores vazios sobrepõem os valores padrão do ambiente, e a última propriedade duplicada prevalece.

Você também pode deixar que LivyConnectionStringBuilder cuide da cotação:

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;

Esses exemplos exigem o driver Microsoft ADO.NET versão 2.0.1 ou posterior. Adicione os identificadores do espaço de trabalho e do lakehouse antes de abrir uma conexão. Ambas as substituições são enviadas na solicitação HC de criação de sessão como entradas conf separadas. Cada substituição deve usar uma destas chaves sensíveis a maiúsculas minúsculas:

  • 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

Aspas malformadas são rejeitadas sem incluir, no erro de análise sintática, o conteúdo da string de conexão.

Use tags consistentes e valores de configuração entre conexões que tenham a intenção de compartilhar capacidade. O Fabric determina se uma solicitação pode usar uma sessão existente ou requer outra sessão.

Configurar o tempo de aquisição

Use as seguintes configurações para controlar quanto tempo o driver espera por uma sessão HC:

Parâmetro Default Entrada válida Behavior
hcAcquireTimeoutSeconds 300 120 a 3.600 segundos Tempo máximo de espera para a sessão de HC ficar pronta.
hcAcquirePollingIntervalMs 1000 De 50 a 30.000 milissegundos Intervalo entre as verificações de status. Em tempo de execução, o driver limita o valor de 100 a 5.000 milissegundos.

Para a maioria das cargas de trabalho, mantenha os valores padrão. Aumente o tempo limite da aquisição apenas quando a inicialização da capacidade normalmente leva mais de cinco minutos.

Use o modo HC com pooling de conexões

O modo HC e o pooling de conexões do ADO.NET atuam em diferentes camadas:

  • O modo HC gerencia a capacidade compartilhada do Fabric Spark e das sessões Livy no servidor.
  • O pooling de conexões ADO.NET reutiliza recursos de conexão gerenciados pelo driver na aplicação cliente.

Você pode ativar ambos os recursos. O pooling de conexões reduz a configuração repetida de conexões do lado do cliente, enquanto o modo HC reduz o provisionamento repetido de sessões Spark do lado do servidor. Dimensione o pool de conexão para a concorrência esperada da aplicação, em vez de usar um pool grande para criar trabalho paralelo desnecessário.

No modo HC, AutoReconnect=true não reproduz de forma transparente um comando falhado após um erro de sessão estagnada. A aplicação recebe a exceção e deve decidir se é seguro tentar novamente a operação.

Desativar o modo HC

Para usar o modo clássico para novas conexões, remova HcEnabled da cadeia de conexão ou defina parafalse:

HcEnabled=false

A mudança afeta novas conexões e não libera as sessões HC agrupadas existentes. Feche ou descarte conexões lógicas normalmente; sessões físicas qualificadas podem permanecer no pool do cliente até serem desativadas.

limitações de ADO.NET

  • Transações não são suportadas.
  • Os comandos suportam apenas o modo de comando de texto. Os modos de comando de procedimento armazenado e de acesso direto à tabela não são suportados.
  • Prepare não faz nada.
  • Um comando deve conter uma instrução; o texto do comando com múltiplas instruções é rejeitado.
  • Use conexões separadas e simultaneamente abertas para cargas de trabalho concorrentes. Comandos em uma conexão compartilham a mesma sessão e REPL.

Mapeamento de tipo de dados

O driver mapeia tipos de dados SQL do Spark para tipos .NET:

Tipo SQL do Spark Tipo de .NET DbType
BOOLEAN bool booleano
TINYINT sbyte SByte
SMALLINT short Int16
INT int Int32
BIGINT long Int64
FLOAT float Solteiro
DUPLO double Double
DECIMAL(p,s) decimal Decimal
STRING string String
VARCHAR(n) string String
CHAR(n) string String
BINÁRIO byte[] Binário
DATE DateTime Date
TIMESTAMP DateTime Data e hora
MATRIZ<T> string Objeto
MAP<K,V> string Objeto
STRUCT string Objeto

Trabalhando com tipos complexos

O caminho de resultado HC não serializa de forma confiável valores nativos aninhados de ARRAY, MAP ou STRUCT como JSON. Converta valores complexos em strings JSON no Spark SQL antes de desserializá-los:

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

Solução de problemas

Esta seção fornece orientações para resolver problemas comuns que você pode encontrar ao usar o driver Microsoft ADO.NET para Engenharia de Dados Fabric.

Problemas comuns

As seções a seguir descrevem problemas comuns e suas soluções:

Falhas na conexão

Problema: Não consigo conectar ao Fabric

Soluções:

  1. Verifique FabricWorkspaceID e FabricLakehouseID são GUIDs corretos
  2. Verifique a autenticação da CLI do Azure: az account show
  3. Verifique se você tem permissões de workspace apropriadas do Fabric
  4. Verificar a conectividade de rede para api.fabric.microsoft.com

Erros de autenticação

Problema: a autenticação falha com a CLI do Azure

Soluções:

  • Executar az login para atualizar credenciais
  • Verifique o locatário correto: az account set --subscription <subscription-id>
  • Verificar a validade do token: az account get-access-token --resource https://api.fabric.microsoft.com

Tempos limite da consulta

Problema: consultas estão atingindo o tempo limite em tabelas grandes

Soluções:

  • Aumentar o tempo limite da instrução: LivyStatementTimeoutSeconds=1200.
  • Usar LIMIT cláusula para restringir o tamanho do resultado durante o desenvolvimento
  • Verifique se o cluster Spark tem recursos adequados

Conexão ou tempo limite para aquisição de HC

Problema: O tempo limite de uma conexão expira ao aguardar uma conexão do pool ou uma sessão HC

Soluções:

  • Para espera no pool de clientes e estabelecimento de conexão HTTP, consulte HttpConnectionTimeoutInSeconds.
  • Para aquisição de HC, aumente hcAcquireTimeoutSeconds dentro da faixa suportada de 120 a 3.600 segundos.
  • Verificar a disponibilidade da capacidade do Fabric
  • Verificar se o workspace não atingiu os limites de sessão

Habilitar registro de log

Ao resolver problemas, registros detalhados podem ajudar a identificar a causa raiz. Configure o log por meio da cadeia de conexão:

Para habilitar o registro em log detalhado por meio de uma string de conexão:

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

Se você não configurar LogFilePath ou não configurar uma configuração de logging global, o driver grava logs no %LOCALAPPDATA%\FabricSparkAdoNet\Logs Windows.

Níveis de log:

  • Trace: mais detalhado, inclui todas as chamadas à API
  • Debug: informações detalhadas de depuração
  • Information: informações gerais (padrão)
  • Warning: somente avisos
  • Error: apenas erros