Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Importante
Esta característica se encuentra en versión preliminar.
ADO.NET es una tecnología de acceso a datos ampliamente adoptada en el ecosistema de .NET que permite a las aplicaciones conectarse y trabajar con datos de bases de datos y plataformas de macrodatos.
Microsoft ADO.NET Driver for Fabric Data Engineering le permite conectar, consultar y administrar cargas de trabajo de Spark en Microsoft Fabric con la confiabilidad y simplicidad de los patrones ADO.NET estándar. Basado en las API livy de Microsoft Fabric, el controlador proporciona conectividad de Spark SQL segura y flexible a las aplicaciones de .NET mediante abstracciones conocidas DbConnection, DbCommandy DbDataReader .
Características clave
-
ADO.NET Compatible: implementación completa de abstracciones de ADO.NET (
DbConnection,DbCommand,DbDataReader,DbParameter,DbProviderFactory) - Autenticación de Microsoft Entra ID: varios flujos de autenticación, como la CLI de Azure, el explorador interactivo, las credenciales de cliente, la autenticación basada en certificados y el token de acceso
- Compatibilidad con consultas nativas de Spark SQL: ejecución directa de instrucciones SQL de Spark con consultas con parámetros
- Compatibilidad completa con tipos de datos: compatibilidad con todos los tipos de datos de Spark SQL, incluidos tipos complejos (ARRAY, MAP, STRUCT)
- Agrupación de conexiones: administración integrada de grupos de conexiones para mejorar el rendimiento
- Reutilización de sesión: administración eficaz de sesiones de Spark para reducir la latencia de inicio
- Captura previa asincrónica: carga de datos en segundo plano para mejorar el rendimiento con grandes conjuntos de resultados
- Reconexión automática: recuperación automática de sesión después de errores de conexión
Nota:
En Apache Spark de código abierto, la base de datos y el esquema se usan como sinónimos. Por ejemplo, la ejecución SHOW SCHEMAS o SHOW DATABASES en un cuaderno de Fabric devuelve el mismo resultado: una lista de todos los esquemas de Lakehouse.
Prerrequisitos
Antes de usar Microsoft ADO.NET Driver for Microsoft Fabric Data Engineering, asegúrese de que tiene:
- Runtime de .NET: .NET 8.0 o posterior
- Microsoft Fabric Access: acceso a un área de trabajo de Microsoft Fabric con funcionalidades de ingeniería de datos
- Credenciales de id. de Azure Entra: credenciales adecuadas para la autenticación
- Identificadores de área de trabajo y Lakehouse: identificadores GUID para tu área de trabajo de Fabric y Lakehouse
- CLI de Azure (opcional): necesario para el método de autenticación de la CLI de Azure
Descarga, inclusión, referencia y comprobación
Descarga del paquete NuGet
Microsoft ADO.NET Driver for Microsoft Fabric Data Engineering versión 1.0.0 está en versión preliminar pública que puede descargar desde estos vínculos del Centro de descarga.
- Descargar Microsoft ADO.NET Driver for Microsoft Fabric Data Engineering (zip)
- Descargar Microsoft ADO.NET Driver for Microsoft Fabric Data Engineering (tar)
Hacer referencia al paquete NuGet en el proyecto
Incluya el paquete NuGet descargado en el proyecto y agregue una referencia del paquete al archivo del proyecto:
<ItemGroup>
<PackageReference Include="Microsoft.Spark.Livy.AdoNet" Version="1.0.0" />
</ItemGroup>
Comprobación de la instalación
Después de incluir y hacer referencia, compruebe que el paquete está disponible en el proyecto:
using Microsoft.Spark.Livy.AdoNet;
// Verify the provider is registered
var factory = LivyProviderFactory.Instance;
Console.WriteLine($"Provider: {factory.GetType().Name}");
Ejemplo de inicio rápido
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 de la cadena de conexión
Formato básico
Microsoft ADO.NET Driver usa el formato estándar de cadena de conexión ADO.NET:
Parameter1=Value1;Parameter2=Value2;...
Parámetros necesarios
| Parámetro | Descripción | Ejemplo |
|---|---|---|
Server |
Punto de conexión de la API de Microsoft Fabric | https://api.fabric.microsoft.com/v1 |
SparkServerType |
Identificador de tipo de servidor | Fabric |
FabricWorkspaceID |
Identificador del área de trabajo de Microsoft Fabric (GUID) | <workspace-id> |
FabricLakehouseID |
Identificador de Lakehouse (GUID) de Microsoft Fabric | <lakehouse-id> |
AuthFlow |
Método de autenticación |
AzureCli, BrowserBased, ClientSecretCredential, ClientCertificateCredential, , AuthAccessToken, FileToken |
Parámetros opcionales
Configuración de conexión
| Parámetro | Tipo | Predeterminado | Descripción |
|---|---|---|---|
LivySessionTimeoutSeconds |
Número entero | 60 |
Tiempo en segundos para esperar a la creación de la sesión |
LivyStatementTimeoutSeconds |
Número entero | 600 |
Tiempo en segundos para esperar la ejecución de instrucciones |
SessionName |
String | (automático) | Nombre personalizado para la sesión de Spark |
AutoReconnect |
Boolean | false |
Habilitación de la recuperación automática de sesión |
Configuración del grupo de conexiones
| Parámetro | Tipo | Predeterminado | Descripción |
|---|---|---|---|
ConnectionPoolEnabled |
Boolean | true |
Habilitación de la agrupación de conexiones |
MinPoolSize |
Número entero | 1 |
Conexiones mínimas en el pool |
MaxPoolSize |
Número entero | 20 |
Número máximo de conexiones en el grupo |
ConnectionMaxIdleTimeMs |
Número entero | 1800000 |
Tiempo de inactividad máximo antes de reciclar la conexión (30 minutos) |
MaxLifetimeMs |
Número entero | 3600000 |
Duración máxima de una conexión agrupada (60 minutos) |
ValidateConnections |
Boolean | true |
Validación de conexiones antes de usar |
ValidationTimeoutMs |
Número entero | 5000 |
Tiempo de espera para la validación de la conexión |
Configuración de registro
| Parámetro | Tipo | Predeterminado | Descripción |
|---|---|---|---|
LogLevel |
String | Information |
Nivel de registro: Trace, Debug, Information, Warning, Error |
LogFilePath |
String | (ninguno) | Ruta de acceso para el registro basado en archivos |
Nota:
Alias de controladores cruzados: El controlador acepta nombres de propiedad JDBC y ODBC además de nombres de ADO.NET nativos (por ejemplo, WorkspaceId se asigna a FabricWorkspaceID, LakehouseId se asigna a FabricLakehouseID). Todos los nombres de propiedad no distinguen mayúsculas de minúsculas.
Ejemplos de cadena de conexión
Conexión básica (autenticación de la CLI de Azure)
Server=https://api.fabric.microsoft.com/v1;SparkServerType=Fabric;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=AzureCli
Con opciones de agrupación de conexiones
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 reconexión automática y el registro
Server=https://api.fabric.microsoft.com/v1;SparkServerType=Fabric;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=AzureCli;AutoReconnect=true;LogLevel=Debug
Autenticación
Microsoft ADO.NET Driver admite varios métodos de autenticación a través de Microsoft Entra ID (anteriormente Azure Active Directory). La autenticación se configura mediante el AuthFlow parámetro en la cadena de conexión.
Métodos de autenticación
| Valor de AuthFlow | Descripción | Mejor para |
|---|---|---|
AzureCli |
Uso de credenciales almacenadas en caché de la CLI de Azure | Desarrollo y pruebas |
BrowserBased |
Autenticación interactiva basada en explorador | Aplicaciones orientadas al usuario |
ClientSecretCredential |
Entidad de servicio con secreto de cliente | Servicios automatizados, trabajos en segundo plano |
ClientCertificateCredential |
Entidad de servicio con certificado | Aplicaciones empresariales |
AuthAccessToken |
Token de acceso de portador adquirido previamente | Escenarios de autenticación personalizados |
Autenticación de la CLI de Azure
Mejor para: Desarrollo y pruebas
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();
Requisitos previos:
- CLI de Azure instalada:
az --version - Iniciado sesión:
az login
Autenticación interactiva del explorador
Mejor para: aplicaciones orientadas al usuario
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
Comportamiento:
- Abre una ventana del explorador para la autenticación de usuario
- Las credenciales se almacenan en caché para las conexiones posteriores
Autenticación de credenciales de cliente (principal de servicio)
Mejor para: Servicios automatizados y trabajos en segundo plano
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();
Parámetros necesarios:
-
AuthTenantID: identificador de inquilino de Azure -
AuthClientID: ID de aplicación (cliente) de Microsoft Entra ID -
AuthClientSecret: secreto de cliente de Microsoft Entra ID
Autenticación basada en certificados
Mejor para: Aplicaciones empresariales que requieren autenticación basada en certificados
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();
Parámetros necesarios:
-
AuthTenantID: identificador de inquilino de Azure -
AuthClientID: ID de aplicación (cliente) -
AuthCertificatePath: ruta de acceso al archivo de certificado PFX/PKCS12 -
AuthCertificatePassword: contraseña de certificado
Autenticación de token de acceso
Mejor para: Escenarios de autenticación personalizados
// 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();
Nota:
Se recomienda encarecidamente evitar credenciales de codificación rígida, como contraseñas, claves, secretos, tokens o certificados en el código. En su lugar, use Azure Key Vault para almacenar estos valores de forma segura y recuperarlos en tiempo de ejecución.
Ejemplos de uso
Conexión básica y consulta
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();
}
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 operaciones 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)");
Trabajar con 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}");
Detección de esquemas
// 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 de 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 de 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...
Asignación de tipos de datos
El controlador asigna los tipos de datos de Spark SQL a tipos de .NET:
| Tipo de SQL de Spark | Tipo de .NET | DbType |
|---|---|---|
| BOOLEAN | bool |
Boolean |
| TINYINT | sbyte |
SByte |
| SMALLINT | short |
Int16 |
| INT | int |
Int32 |
| BIGINT | long |
Int64 |
| FLOTAR | float |
Soltero |
| DOUBLE | double |
Double |
| DECIMAL(p,s) | decimal |
Decimal |
| STRING | string |
String |
| VARCHAR(n) | string |
String |
| CHAR(n) | string |
String |
| BINARIO | byte[] |
Binary |
| FECHA | DateTime |
Fecha |
| TIMESTAMP | DateTime |
DateTime |
| ARRAY<T> |
T[] o string (JSON) |
Objeto |
| MAP<K,V> |
Dictionary<K,V> o string (JSON) |
Objeto |
| ESTRUCTURA |
object o string (JSON) |
Objeto |
Trabajar con tipos complejos
Los tipos complejos (ARRAY, MAP, STRUCT) se devuelven como cadenas JSON de forma predeterminada:
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);
}
Solución de problemas
En esta sección se proporcionan instrucciones para resolver problemas comunes que pueden surgir al usar Microsoft ADO.NET Driver for Microsoft Fabric Data Engineering.
Problemas comunes
En las secciones siguientes se describen problemas comunes y sus soluciones:
Fallos de conexión
Problema: no se puede conectar a Microsoft Fabric
Soluciones:
- Verifique que
FabricWorkspaceIDyFabricLakehouseIDsean GUID correctos - Compruebe la autenticación de la CLI de Azure:
az account show - Asegúrese de que tiene los permisos adecuados del área de trabajo de Fabric.
- Comprobación de la conectividad de red a
api.fabric.microsoft.com
Errores de autenticación
Problema: error de autenticación con la CLI de Azure
Soluciones:
- Ejecución
az loginpara actualizar las credenciales - Compruebe el inquilino correcto:
az account set --subscription <subscription-id> - Comprobar la validez del token:
az account get-access-token --resource https://api.fabric.microsoft.com
Tiempos de espera de consulta agotados
Problema: Las consultas agotan el tiempo de espera en tablas grandes
Soluciones:
- Incrementar el tiempo de espera de la instrucción:
LivyStatementTimeoutSeconds=300 - Use la cláusula
LIMITpara restringir el tamaño del resultado durante el desarrollo. - Asegúrese de que el clúster de Spark tiene recursos adecuados
Tiempo de espera de creación de la sesión
Problema: El tiempo de espera de la conexión se agota durante la creación de la sesión
Soluciones:
- Aumentar el tiempo de espera de la sesión:
LivySessionTimeoutSeconds=120 - Comprobación de la disponibilidad de la capacidad de Fabric
- Verificar que el área de trabajo no haya alcanzado los límites de sesión
Habilitar registro
Al solucionar problemas, habilitar el registro detallado puede ayudarle a identificar la causa principal de los problemas. Puede habilitar el registro a través de la cadena de conexión o mediante programación.
Para habilitar el registro detallado a través de la cadena de conexión:
LogLevel=Debug
O bien, configure mediante programación:
using Microsoft.Extensions.Logging;
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Debug);
});
// Logging is automatically integrated with the connection
Niveles de registro:
-
Trace: La máxima verbosidad, incluye todas las llamadas a la API. -
Debug: información detallada de depuración -
Information: información general (valor predeterminado) -
Warning: solo advertencias -
Error: solo errores