Introducción al espacio de nombres Microsoft.Data.SqlClient
El espacio de nombres Microsoft.Data.SqlClient es básicamente una nueva versión del espacio de nombres System.Data.SqlClient. Microsoft.Data.SqlClient generalmente mantiene la misma API y la misma compatibilidad con System.Data.SqlClient. Migrar de System.Data.SqlClient a Microsoft.Data.SqlClient es sencillo para la mayoría de las aplicaciones. Agregue una dependencia de NuGet en Microsoft.Data.SqlClient y actualice las referencias e instrucciones using
a Microsoft.Data.SqlClient.
Hay algunas diferencias en las API menos usadas en comparación con System.Data.SqlClient que pueden afectar a algunas aplicaciones. Acerca de esas diferencias, consulte esta útil hoja de referencia rápida sobre portabilidad.
Referencia de API
Los detalles de la API Microsoft.Data.SqlClient se pueden encontrar en el explorador de la API de .NET.
Notas de la versión de Microsoft.Data.SqlClient 5.2
Nuevas características de la versión 5.2
- Se ha agregado compatibilidad con
SqlDiagnosticListener
en .NET Standard. #1931 - Se ha agregado la nueva propiedad
RowsCopied64
aSqlBulkCopy
. N.º 2004 Más información - Se ha agregado una nueva API
AccessTokenCallBack
aSqlConnection
. N.º 1260 Más información - Se ha agregado compatibilidad con la opción de registro
SuperSocketNetLib
para cifrar en .NET en Windows. #2047 - Se ha agregado compatibilidad de
SqlBatch
con .NET 6+ n.º 1825, n.º 2223 Más información - Se ha agregado compatibilidad con la autenticación de la identidad de cargas de trabajo #2159, #2264
- Se ha agregado compatibilidad de localización en .NET #2210
- Se ha agregado compatibilidad con la intercalación georgiana #2194
- Se ha agregado compatibilidad con sistemas Big Endian #2170
- Se ha agregado compatibilidad con .NET 8 #2230
- Se ha agregado una versión explícita para las principales dependencias de la versión de .NET en System.Runtime.Caching 8.0.0, System.Configuration.ConfigurationManager 8.0.0 y System.Diagnostics.DiagnosticSource 8.0.0 #2303
- Se ha agregado la capacidad de generar símbolos de depuración en un archivo de paquete independiente #2137
Se ha agregado una nueva propiedad RowsCopied64
a SqlBulkCopy
SqlBulkCopy tiene una nueva propiedad RowsCopied64
que admite long
tipos de valor.
Tenga en cuenta que el comportamiento SqlBulkCopy.RowsCopied
existente no cambia. Cuando el valor supera int.MaxValue
, RowsCopied
puede devolver un número negativo.
Ejemplo de uso:
using (SqlConnection srcConn = new SqlConnection(srcConstr))
using (SqlCommand srcCmd = new SqlCommand("select top 5 * from employees", srcConn))
{
srcConn.Open();
using (DbDataReader reader = srcCmd.ExecuteReader())
{
using (SqlBulkCopy bulkcopy = new SqlBulkCopy(dstConn))
{
bulkcopy.DestinationTableName = dstTable;
SqlBulkCopyColumnMappingCollection ColumnMappings = bulkcopy.ColumnMappings;
ColumnMappings.Add("EmployeeID", "col1");
ColumnMappings.Add("LastName", "col2");
ColumnMappings.Add("FirstName", "col3");
bulkcopy.WriteToServer(reader);
long rowsCopied = bulkcopy.RowsCopied64;
}
}
}
Se ha agregado una nueva propiedad AccessTokenCallBack
a SqlConnection
SqlConnection admite la autenticación TokenCredential
mediante la introducción de una nueva propiedad AccessTokenCallBack
como delegado de Func<SqlAuthenticationParameters, CancellationToken,Task<SqlAuthenticationToken>>
para devolver un token de acceso de autenticación federada.
Ejemplo de uso:
using Microsoft.Data.SqlClient;
using Azure.Identity;
const string defaultScopeSuffix = "/.default";
string connectionString = GetConnectionString();
DefaultAzureCredential credential = new();
using SqlConnection connection = new(connectionString);
connection.AccessTokenCallback = async (authParams, cancellationToken) =>
{
string scope = authParams.Resource.EndsWith(defaultScopeSuffix)
? authParams.Resource
: $"{authParams.Resource}{defaultScopeSuffix}";
AccessToken token = await cred.GetTokenAsync(
new TokenRequestContext([scope]),
cancellationToken);
return new SqlAuthenticationToken(token.Token, token.ExpiresOn);
}
connection.Open();
Console.WriteLine("ServerVersion: {0}", connection.ServerVersion);
Console.WriteLine("State: {0}", connection.State);
API SqlBatch
Ejemplo de uso:
using Microsoft.Data.SqlClient;
class Program
{
static void Main()
{
string str = "Data Source=(local);Initial Catalog=Northwind;"
+ "Integrated Security=SSPI;Encrypt=False";
RunBatch(str);
}
static void RunBatch(string connString)
{
using var connection = new SqlConnection(connString);
connection.Open();
var batch = new SqlBatch(connection);
const int count = 10;
const string parameterName = "parameter";
for (int i = 0; i < count; i++)
{
var batchCommand = new SqlBatchCommand($"SELECT @{parameterName} as value");
batchCommand.Parameters.Add(new SqlParameter(parameterName, i));
batch.BatchCommands.Add(batchCommand);
}
// Optionally Prepare
batch.Prepare();
var results = new List<int>(count);
using (SqlDataReader reader = batch.ExecuteReader())
{
do
{
while (reader.Read())
{
results.Add(reader.GetFieldValue<int>(0));
}
} while (reader.NextResult());
}
Console.WriteLine(string.Join(", ", results));
}
}
Compatibilidad con la plataforma de destino 5.2
- .NET Framework 4.6.2+ (Windows x86, Windows x64)
- .NET 6.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
Las notas de la versión completas, incluidas las dependencias, están disponibles en el repositorio de GitHub de las notas de la versión 5.2.
Cambios importantes en la versión 5.1
Nuevas características de la versión 5.1
- Se ha agregado compatibilidad con
DateOnly
yTimeOnly
para el valor deSqlParameter
yGetFieldValue
. #1813 - Se ha agregado compatibilidad con TLS 1.3 para .NET Core y SNI Native. #1821
- Se ha agregado la configuración de
ServerCertificate
paraEncrypt=Mandatory
oEncrypt=Strict
. N.º 1822 Más información - Se ha agregado compatibilidad con Windows ARM64 al establecer como destino .NET Framework. #1828
Certificado de servidor
El valor predeterminado de la configuración de conexión de ServerCertificate
es una cadena vacía. Cuando se establece Encrypt
en Mandatory
o Strict
, se puede usar ServerCertificate
para especificar una ruta de acceso en el sistema de archivos a un archivo de certificado para coincidir con el certificado TLS/SSL del servidor. El certificado especificado debe ser una coincidencia exacta para que sea válido. Los formatos de certificado permitidos son PEM
, DER
y CER
. Presentamos un ejemplo de uso:
"Data Source=...;Encrypt=Strict;ServerCertificate=C:\\certificates\\server.cer"
Compatibilidad con la plataforma de destino 5.1
- .NET Framework 4.6.2+ (Windows x86, Windows x64)
- .NET 6.0+ (Windows x86, Windows x64, Windows ARM64, Windows Azure Resource Manager, Linux, macOS)
- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
Las notas de la versión completas, incluidas las dependencias, están disponibles en el repositorio de GitHub de las notas de la versión 5.1.
Notas de la versión de Microsoft.Data.SqlClient 5.0
Cambios importantes en la versión 5.0
- Se ha quitado la compatibilidad con .NET Framework 4.6.1. #1574.
- Se ha agregado una dependencia en el paquete Microsoft.SqlServer.Server. Esta nueva dependencia puede provocar conflictos de espacio de nombres si la aplicación hace referencia a ese espacio de nombres y sigue teniendo referencias de paquete (directas o indirectas) a System.Data.SqlClient desde .NET Core.
- Se han quitado las clases del espacio de nombres
Microsoft.Data.SqlClient.Server
y se han reemplazado por tipos admitidos del paquete Microsoft.SqlServer.Server. #1585. Las clases y enumeraciones afectadas son:- Microsoft.Data.SqlClient.Server.IBinarySerialize -> Microsoft.SqlServer.Server.IBinarySerialize
- Microsoft.Data.SqlClient.Server.InvalidUdtException -> Microsoft.SqlServer.Server.InvalidUdtException
- Microsoft.Data.SqlClient.Server.SqlFacetAttribute -> Microsoft.SqlServer.Server.SqlFacetAttribute
- Microsoft.Data.SqlClient.Server.SqlFunctionAttribute -> Microsoft.SqlServer.Server.SqlFunctionAttribute
- Microsoft.Data.SqlClient.Server.SqlMethodAttribute -> Microsoft.SqlServer.Server.SqlMethodAttribute
- Microsoft.Data.SqlClient.Server.SqlUserDefinedAggregateAttribute -> Microsoft.SqlServer.Server.SqlUserDefinedAggregateAttribute
- Microsoft.Data.SqlClient.Server.SqlUserDefinedTypeAttribute -> Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute
- (enum) Microsoft.Data.SqlClient.Server.DataAccessKind -> Microsoft.SqlServer.Server.DataAccessKind
- (enum) Microsoft.Data.SqlClient.Server.Format -> Microsoft.SqlServer.Server.Format
- (enum) Microsoft.Data.SqlClient.Server.SystemDataAccessKind -> Microsoft.SqlServer.Server.SystemDataAccessKind
Nuevas características de la versión 5.0
- Se ha agregado compatibilidad con
TDS8
. Para usar TDS 8, los usuarios deben especificar Encrypt=Strict en la cadena de conexión. N.º 1608 Más información - Se ha agregado funcionalidad para especificar el SPN del servidor y el SPN del servidor de conmutación por error en la conexión. N.º 1607 Más información
- Se ha agregado compatibilidad con alias al establecer .NET Core en Windows como destino. N.º 1588 Más información
- Se ha agregado SqlDataSourceEnumerator. #1430. Más información
- Se ha agregado un nuevo modificador AppContext para suprimir las advertencias de TLS no seguras. #1457. Más información
Seguridad mejorada en TDS 8
Para usar TDS 8, especifique Encrypt=Strict en la cadena de conexión. El modo strict deshabilita TrustServerCertificate (tratado siempre como False en el modo strict). Se ha agregado HostNameInCertificate para ayudar en algunos escenarios del modo strict. TDS 8 comienza y continúa toda la comunicación del servidor en una conexión TLS cifrada segura.
Se han agregado nuevos valores de Encrypt para aclarar el comportamiento del cifrado de la conexión. Encrypt=Mandatory
equivale a Encrypt=True
y cifra las conexiones durante la negociación de conexión de TDS. Encrypt=Optional
equivale a Encrypt=False
y solo cifra la conexión si el servidor indica al cliente que el cifrado es necesario durante la negociación de la conexión de TDS.
Para más información sobre el cifrado de conexiones al servidor, consulte Cifrado y validación de certificados.
HostNameInCertificate
se puede especificar en la cadena de conexión cuando se usan alias para conectarse con cifrado a un servidor que tenga un certificado de servidor con un nombre diferente o un nombre de sujeto alternativo al nombre usado por el cliente para identificar el servidor (alias DNS, por ejemplo). Ejemplo de uso: HostNameInCertificate=MyDnsAliasName
Dirección SPN del servidor
Al conectarse en un entorno que tiene una topografía de dominio/bosque única, es posible que tenga requisitos específicos para los SPN de servidor. La configuración de la cadena de conexión ServerSPN/SPN del servidor y FailoverServerSPN/SPN del servidor de conmutación por error se puede usar para invalidar los SPN de servidor generados automáticamente que se usan durante la autenticación integrada en un entorno de dominio.
Compatibilidad con alias de SQL
Los usuarios pueden configurar alias con el Administrador de configuración de SQL Server. Estos alias se almacenan en el Registro de Windows y ya se admiten cuando el destino es .NET Framework. Esta versión ofrece compatibilidad con alias cuando se establecen .NET o .NET Core en Windows como destino.
Compatibilidad con el enumerador de orígenes de datos de SQL
Proporciona un mecanismo para enumerar todas las instancias disponibles de SQL Server incluidas en la red local.
using Microsoft.Data.Sql;
static void Main()
{
// Retrieve the enumerator instance and then the data.
SqlDataSourceEnumerator instance =
SqlDataSourceEnumerator.Instance;
System.Data.DataTable table = instance.GetDataSources();
// Display the contents of the table.
DisplayData(table);
Console.WriteLine("Press any key to continue.");
Console.ReadKey();
}
private static void DisplayData(System.Data.DataTable table)
{
foreach (System.Data.DataRow row in table.Rows)
{
foreach (System.Data.DataColumn col in table.Columns)
{
Console.WriteLine("{0} = {1}", col.ColumnName, row[col]);
}
Console.WriteLine("============================");
}
}
Supresión de advertencias de TLS no seguro
Cuando se usa una versión de TLS inferior a la 1.2 para negociar con el servidor, se muestra una advertencia de seguridad en la consola. Esta advertencia se puede suprimir en la conexión de SQL cuando Encrypt = false
habilitando el siguiente modificador de AppContext en el inicio de la aplicación:
Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning
Compatibilidad con la plataforma de destino 5.0
- .NET Framework 4.6.2+ (Windows x86, Windows x64)
- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
Las notas de la versión completas, incluidas las dependencias, están disponibles en el repositorio de GitHub de las notas de la versión 5.0.
Notas de la versión de Microsoft.Data.SqlClient 4.1
Las notas completas de la versión, incluidas las dependencias, están disponibles en el repositorio de GitHub: Notas de la versión 4.1.
Nuevas características de la versión 4.1
Introducción al protocolo de atestación Ninguno
Se permite un nuevo protocolo de atestación denominado None
en la cadena de conexión. Este protocolo permite a los usuarios renunciar a la atestación de enclave para los enclaves VBS
. Cuando se establece este protocolo, la propiedad URL de atestación de enclave es opcional.
Ejemplo de cadena de conexión:
//Attestation protocol NONE with no URL
"Data Source = {server}; Initial Catalog = {db}; Column Encryption Setting = Enabled; Attestation Protocol = None;"
Compatibilidad con la plataforma de destino 4.1
- .NET Framework 4.6.1+ (Windows x86, Windows x64)
- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
Notas de la versión de Microsoft.Data.SqlClient 4.0
Las notas completas de la versión, incluidas las dependencias, están disponibles en el repositorio de GitHub: Notas de la versión 4.0.
Cambios importantes en la versión 4.0
- Se ha cambiado la propiedad existente de cadena de conexión
Encrypt
atrue
de manera predeterminada. N.º 1210 Más información - El controlador ahora inicia
SqlException
que sustituyeAggregateException
de los modos de autenticación de Active Directory. N.º 1213 - Se ha eliminado la propiedad de conexión
Asynchronous Processing
obsoleta de .NET Framework. N.º 1148 - Se ha quitado el conmutador de seguridad
Configurable Retry Logic
. N.º 1254 Más información - Se ha eliminado la compatibilidad con .NET Core 2.1 N.º 1272.
- [.NET Framework] No se produce una excepción si se proporciona un identificador de usuario en la cadena de conexión cuando se usa la autenticación de
Active Directory Integrated
#1359
Nuevas características de la versión 4.0
Cifrado del valor predeterminado establecido en true
El valor predeterminado de la configuración de conexión Encrypt
se ha cambiado de false
a true
. Con el creciente uso de las bases de datos en la nube y la necesidad de garantizar que esas conexiones sean seguras, ha llegado el momento de este cambio importante de compatibilidad con versiones anteriores.
Asegurarse de que las conexiones no se pueden realizar cuando se requiere cifrado
En escenarios en los que las bibliotecas de cifrado de cliente estaban deshabilitadas o no estaban disponibles, era posible realizar conexiones sin cifrar cuando Encrypt se estableció en true o el servidor requería cifrado.
Cambio de contexto de aplicación para usar los protocolos predeterminados del sistema
El controlador no admite TLS 1.3; por tanto, se ha quitado de la lista de protocolos admitidos de forma predeterminada. Los usuarios pueden volver a forzar el uso de los protocolos de cliente del sistema operativo, habilitando el cambio de contexto de aplicación a continuación:
Switch.Microsoft.Data.SqlClient.UseSystemDefaultSecureProtocols
Habilitación del enlace de parámetros optimizados
Microsoft.Data.SqlClient presenta una nueva API SqlCommand
, EnableOptimizedParameterBinding
, para mejorar el rendimiento de las consultas con un gran número de parámetros. Esta propiedad está deshabilitada de forma predeterminada. Si se establece en true
, los nombres de parámetro no se envían a la instancia de SQL Server cuando se ejecuta el comando.
public class SqlCommand
{
public bool EnableOptimizedParameterBinding { get; set; }
}
Eliminación del conmutador de seguridad lógica de reintento configurable
El cambio de contexto de aplicación "Switch.Microsoft.Data.SqlClient.EnableRetryLogic" ya no es necesario para usar la característica lógica de reintento configurable. La característica ahora se admite en producción. El comportamiento predeterminado de la característica seguirá siendo una directiva sin reintentos, que las aplicaciones cliente tendrán que invalidar para habilitar los reintentos.
Compatibilidad con instancias compartidas de SqlLocalDb
Ahora se admiten instancias compartidas de SqlLocalDb cuando se usa SNI administrado.
- Escenarios posibles:
(localdb)\.
(se conecta a la instancia predeterminada de SqlLocalDb)(localdb)\<named instance>
(localdb)\.\<shared instance name>
(*compatibilidad recién agregada)
Compatibilidad con GetFieldValueAsync<T>
y GetFieldValue<T>
para los tipos XmlReader
, TextReader
, Stream
Ahora se admiten los tipos XmlReader
, TextReader
, Stream
al usar GetFieldValueAsync<T>
y GetFieldValue<T>
.
Ejemplo de uso:
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(query, connection))
{
connection.Open();
using (SqlDataReader reader = await command.ExecuteReaderAsync())
{
if (await reader.ReadAsync())
{
using (Stream stream = await reader.GetFieldValueAsync<Stream>(1))
{
// Continue to read from stream
}
}
}
}
}
Compatibilidad con la plataforma de destino 4.0
- .NET Framework 4.6.1+ (Windows x86, Windows x64)
- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
Notas de la versión de Microsoft.Data.SqlClient 3.0
Las notas completas de la versión, incluidas las dependencias, están disponibles en el repositorio de GitHub: Notas de la versión 3.0.
Cambios importantes en la versión 3.0
- La versión de .NET Framework mínima admitida ha aumentado a v4.6.1. .NET Framework v4.6.0 ya no se admite. N.º 899.
- La propiedad de conexión
User Id
ahora requiereClient Id
en lugar deObject Id
para la identidad administrada asignada por el usuario. N.º 1010. Más información. SqlDataReader
ahora devuelve un valorDBNull
en lugar de unbyte[]
vacío. El comportamiento heredado se puede habilitar mediante el establecimiento del modificadorAppContext
Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior. N.º 998. Más información.
Nuevas características de la versión 3.0
Lógica de reintento configurable
Esta nueva característica introduce compatibilidad configurable para que las aplicaciones cliente vuelvan a intentar errores "transitorios" o "recuperables". La configuración se puede realizar mediante archivos de configuración de aplicación o código y se pueden aplicar operaciones de reintento para abrir una conexión o ejecutar un comando. Esta característica está deshabilitada de forma predeterminada y se encuentra actualmente en versión preliminar. Para habilitar esta compatibilidad, las aplicaciones cliente deben activar el siguiente modificador de seguridad:
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.EnableRetryLogic", true);
Una vez que se ha habilitado el modificador AppContext de .NET, se puede definir una directiva lógica de reintentos para SqlConnection
y SqlCommand
de forma independiente, o en conjunto mediante varias opciones de personalización.
Se han introducido nuevas API públicas en SqlConnection
y SqlCommand
para registrar una implementación de SqlRetryLogicBaseProvider
personalizada:
public SqlConnection
{
public SqlRetryLogicBaseProvider RetryLogicProvider;
}
public SqlCommand
{
public SqlRetryLogicBaseProvider RetryLogicProvider;
}
Aquí encontrará ejemplos de uso de API: .
using Microsoft.Data.SqlClient;
/// Detecting retriable exceptions is a vital part of the retry pattern.
/// Before applying retry logic it is important to investigate exceptions and choose a retry provider that best fits your scenario.
/// First, log your exceptions and find transient faults.
/// The purpose of this sample is to illustrate how to use this feature and the condition might not be realistic.
class RetryLogicSample
{
private const string DefaultDB = "Northwind";
private const string CnnStringFormat = "Server=localhost; Initial Catalog={0}; Integrated Security=true; pooling=false;";
private const string DropDatabaseFormat = "DROP DATABASE {0}";
// For general use
private static SqlConnection s_generalConnection = new SqlConnection(string.Format(CnnStringFormat, DefaultDB));
static void Main(string[] args)
{
// 1. Define the retry logic parameters
var options = new SqlRetryLogicOption()
{
NumberOfTries = 5,
MaxTimeInterval = TimeSpan.FromSeconds(20),
DeltaTime = TimeSpan.FromSeconds(1)
};
// 2. Create a retry provider
var provider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(options);
// define the retrying event to report the execution attempts
provider.Retrying += (object s, SqlRetryingEventArgs e) =>
{
int attempts = e.RetryCount + 1;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"attempt {attempts} - current delay time:{e.Delay} \n");
Console.ForegroundColor = ConsoleColor.DarkGray;
if (e.Exceptions[e.Exceptions.Count - 1] is SqlException ex)
{
Console.WriteLine($"{ex.Number}-{ex.Message}\n");
}
else
{
Console.WriteLine($"{e.Exceptions[e.Exceptions.Count - 1].Message}\n");
}
// It is not a good practice to do time-consuming tasks inside the retrying event which blocks the running task.
// Use parallel programming patterns to mitigate it.
if (e.RetryCount == provider.RetryLogic.NumberOfTries - 1)
{
Console.WriteLine("This is the last chance to execute the command before throwing the exception.");
Console.WriteLine("Press Enter when you're ready:");
Console.ReadLine();
Console.WriteLine("continue ...");
}
};
// Open the general connection.
s_generalConnection.Open();
try
{
// Assume the database is being created and other services are going to connect to it.
RetryConnection(provider);
}
catch
{
// exception is thrown if connecting to the database isn't successful.
throw;
}
}
private static void ExecuteCommand(SqlConnection cn, string command)
{
using var cmd = cn.CreateCommand();
cmd.CommandText = command;
cmd.ExecuteNonQuery();
}
private static void RetryConnection(SqlRetryLogicBaseProvider provider)
{
// Change this if you already have a database with the same name in your database.
string dbName = "Invalid_DB_Open";
// Create a connection to an invalid database.
using var cnn = new SqlConnection(string.Format(CnnStringFormat, dbName));
// 3. Assign the `provider` to the connection
cnn.RetryLogicProvider = provider;
Console.WriteLine($"Connecting to the [{dbName}] ...");
// Manually execute the following command in SSMS to create the invalid database while the SqlConnection is attempting to connect to it.
// >> CREATE DATABASE Invalid_DB_Open;
Console.WriteLine($"Manually, run the 'CREATE DATABASE {dbName};' in the SQL Server before exceeding the {provider.RetryLogic.NumberOfTries} attempts.");
// the connection tries to connect to the database 5 times
Console.WriteLine("The first attempt, before getting into the retry logic.");
cnn.Open();
Console.WriteLine($"Connected to the [{dbName}] successfully.");
cnn.Close();
// Drop it after test
ExecuteCommand(s_generalConnection, string.Format(DropDatabaseFormat, dbName));
Console.WriteLine($"The [{dbName}] is removed.");
}
}
/// Detecting retriable exceptions is a vital part of the retry pattern.
/// Before applying retry logic it is important to investigate exceptions and choose a retry provider that best fits your scenario.
/// First, log your exceptions and find transient faults.
/// The purpose of this sample is to illustrate how to use this feature and the condition might not be realistic.
private const string DefaultDB = "Northwind";
private const string CnnStringFormat = "Server=localhost; Initial Catalog={0}; Integrated Security=true; pooling=false;";
private const string DropDatabaseFormat = "DROP DATABASE {0}";
private const string CreateDatabaseFormat = "CREATE DATABASE {0}";
// For general use
private static SqlConnection s_generalConnection = new SqlConnection(string.Format(CnnStringFormat, DefaultDB));
static void Main(string[] args)
{
// 1. Define the retry logic parameters
var options = new SqlRetryLogicOption()
{
NumberOfTries = 5,
MaxTimeInterval = TimeSpan.FromSeconds(20),
DeltaTime = TimeSpan.FromSeconds(1),
AuthorizedSqlCondition = null,
// error number 3702 : Cannot drop database "xxx" because it is currently in use.
TransientErrors = new int[] {3702}
};
// 2. Create a retry provider
var provider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(options);
// define the retrying event to report execution attempts
provider.Retrying += (object s, SqlRetryingEventArgs e) =>
{
int attempts = e.RetryCount + 1;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"attempt {attempts} - current delay time:{e.Delay} \n");
Console.ForegroundColor = ConsoleColor.DarkGray;
if (e.Exceptions[e.Exceptions.Count - 1] is SqlException ex)
{
Console.WriteLine($"{ex.Number}-{ex.Message}\n");
}
else
{
Console.WriteLine($"{e.Exceptions[e.Exceptions.Count - 1].Message}\n");
}
// It is not good practice to do time-consuming tasks inside the retrying event which blocks the running task.
// Use parallel programming patterns to mitigate it.
if (e.RetryCount == provider.RetryLogic.NumberOfTries - 1)
{
Console.WriteLine("This is the last chance to execute the command before throwing the exception.");
Console.WriteLine("Press Enter when you're ready:");
Console.ReadLine();
Console.WriteLine("continue ...");
}
};
// Open a general connection.
s_generalConnection.Open();
try
{
// Assume the database is creating and other services are going to connect to it.
RetryCommand(provider);
}
catch
{
s_generalConnection.Close();
// exception is thrown if connecting to the database isn't successful.
throw;
}
s_generalConnection.Close();
}
private static void ExecuteCommand(SqlConnection cn, string command)
{
using var cmd = cn.CreateCommand();
cmd.CommandText = command;
cmd.ExecuteNonQuery();
}
private static void FindActiveSessions(SqlConnection cnn, string dbName)
{
using var cmd = cnn.CreateCommand();
cmd.CommandText = "DECLARE @query NVARCHAR(max) = '';" + Environment.NewLine +
$"SELECT @query = @query + 'KILL ' + CAST(spid as varchar(50)) + ';' FROM sys.sysprocesses WHERE dbid = DB_ID('{dbName}')" + Environment.NewLine +
"SELECT @query AS Active_sessions;";
var reader = cmd.ExecuteReader();
if (reader.Read())
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write($">> Execute the '{reader.GetString(0)}' command in SQL Server to unblock the running task.");
Console.ResetColor();
}
reader.Close();
}
var RetryLogicOption = new SqlRetryLogicOption()
{
NumberOfTries = 5,
// Declare the error number 102 as a transient error to apply the retry logic when it occurs.
TransientErrors = new int[] { 102 },
// When a SqlCommand executes out of a transaction,
// the retry logic will apply if it contains a 'select' keyword.
AuthorizedSqlCondition = x => string.IsNullOrEmpty(x)
|| Regex.IsMatch(x, @"\b(SELECT)\b", RegexOptions.IgnoreCase),
DeltaTime = TimeSpan.FromSeconds(1),
MaxTimeInterval = TimeSpan.FromSeconds(60),
MinTimeInterval = TimeSpan.FromSeconds(3)
};
También se han introducido nuevas secciones de configuración para realizar el mismo registro desde los archivos de configuración, sin necesidad de modificar el código existente:
<section name="SqlConfigurableRetryLogicConnection"
type="Microsoft.Data.SqlClient.SqlConfigurableRetryConnectionSection, Microsoft.Data.SqlClient"/>
<section name="SqlConfigurableRetryLogicCommand"
type="Microsoft.Data.SqlClient.SqlConfigurableRetryCommandSection, Microsoft.Data.SqlClient"/>
Este es un ejemplo sencillo del uso de las nuevas secciones de configuración en los archivos de configuración:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="SqlConfigurableRetryLogicConnection"
type="Microsoft.Data.SqlClient.SqlConfigurableRetryConnectionSection, Microsoft.Data.SqlClient"/>
<section name="SqlConfigurableRetryLogicCommand"
type="Microsoft.Data.SqlClient.SqlConfigurableRetryCommandSection, Microsoft.Data.SqlClient"/>
<section name="AppContextSwitchOverrides"
type="Microsoft.Data.SqlClient.AppContextSwitchOverridesSection, Microsoft.Data.SqlClient"/>
</configSections>
<!--Enable safety switch in .NET Core-->
<AppContextSwitchOverrides value="Switch.Microsoft.Data.SqlClient.EnableRetryLogic=true"/>
<!--Retry method for SqlConnection-->
<SqlConfigurableRetryLogicConnection retryMethod ="CreateFixedRetryProvider" numberOfTries ="3" deltaTime ="00:00:10" maxTime ="00:00:30"
transientErrors="40615" />
<!--Retry method for SqlCommand containing SELECT queries-->
<SqlConfigurableRetryLogicCommand retryMethod ="CreateIncrementalRetryProvider" numberOfTries ="5" deltaTime ="00:00:10" maxTime ="00:01:10"
authorizedSqlCondition="\b(SELECT)\b" transientErrors="102, 4060, 0"/>
</configuration>
Como alternativa, las aplicaciones pueden implementar su propio proveedor de la clase base SqlRetryLogicBaseProvider
y registrarlo con SqlConnection
/SqlCommand
.
Contadores de eventos
Ahora están disponibles los siguientes contadores para las aplicaciones que tienen como destino .NET Core 3.1+ y .NET Standard 2.1+:
NOMBRE | Nombre para mostrar | Descripción |
---|---|---|
active-hard-connections | Conexiones activas reales realizadas actualmente a servidores | Número de conexiones que están abiertas actualmente a servidores de bases de datos. |
hard-connects | Velocidad de conexión real a los servidores | Número de conexiones por segundo que se abren a servidores de bases de datos. |
hard-disconnects | Velocidad de desconexión real de los servidores | Número de desconexiones por segundo que se producen con servidores de bases de datos. |
active-soft-connects | Conexiones activas recuperadas del grupo de conexiones | Número de conexiones ya abiertas que se consumen desde el grupo de conexiones. |
soft-connects | Velocidad de las conexiones recuperadas del grupo de conexiones | Número de conexiones por segundo que se consumen desde el grupo de conexiones. |
soft-disconnects | Velocidad de las conexiones recuperadas del grupo de conexiones | Número de conexiones por segundo que se devuelven al grupo de conexiones. |
number-of-non-pooled-connections | Número de conexiones que no usan la agrupación de conexiones | Número de conexiones activas que no están agrupadas. |
number-of-pooled-connections | Número de conexiones administradas por el grupo de conexiones | El número de conexiones activas que administra la infraestructura de agrupación de conexiones. |
number-of-active-connection-pool-groups | Número de cadenas de conexión únicas activas | Número de grupos de conexiones activos y únicos. Este contador depende del número de cadenas de conexión única que haya en el dominio de aplicación. |
number-of-inactive-connection-pool-groups | Número de cadenas de conexión únicas a la espera de ser eliminadas | El número de conjuntos de grupos de conexiones únicas marcados para ser eliminados. Este contador depende del número de cadenas de conexión única que haya en el dominio de aplicación. |
number-of-active-connection-pools | Número de grupos de conexiones activas | El número total de grupos de conexiones. |
number-of-inactive-connection-pools | Número de grupos de conexiones inactivas | Número de grupos de conexiones inactivas sin actividad reciente y en espera de ser eliminadas. |
number-of-active-connections | Número de conexiones activas | Número de conexiones actualmente en uso. |
number-of-free-connections | Número de conexiones listas en el grupo de conexiones | Número de conexiones abiertas que se pueden usar en los grupos de conexiones. |
number-of-stasis-connections | Número de conexiones actualmente a la espera de estar listas | Número de conexiones actualmente a la espera de la finalización de una acción y que no están disponibles para su uso por parte de la aplicación. |
number-of-reclaimed-connections | Número de conexiones reclamadas desde la recolección de elementos no utilizados | Número de conexiones que se han reclamado mediante la recolección de elementos no utilizados en las que la aplicación no llamó a Close ni a Dispose . Nota: No cerrar o eliminar explícitamente las conexiones afecta el rendimiento. |
Estos contadores se pueden usar con las herramientas de la CLI global de .NET Core: dotnet-counters
y dotnet-trace
en Windows o Linux y PerfView en Windows, con Microsoft.Data.SqlClient.EventSource
como nombre del proveedor. Para obtener más información, vea Recuperación de valores del contador de eventos.
dotnet-counters monitor Microsoft.Data.SqlClient.EventSource -p
PerfView /onlyProviders=*Microsoft.Data.SqlClient.EventSource:EventCounterIntervalSec=1 collect
Introducción a la dependencia de Azure Identity
Microsoft.Data.SqlClient ahora depende de la biblioteca Azure.Identity para adquirir tokens para los modos de autenticación "Identidad administrada de Active Directory/MSI" y "Entidad de servicio de Active Directory". Este cambio conlleva los cambios siguientes en el área expuesta pública:
- Cambio importante
La propiedad de conexión "User Id" ahora requiere "Client Id" en lugar de Object Id" para la "Identidad administrada asignada por el usuario". - API pública
Nueva propiedad pública de solo lectura:SqlAuthenticationParameters.ConnectionTimeout
- Dependencia
Azure.Identity v1.3.0
Mejoras de seguimiento de eventos en SNI.dll
Las versiones de Microsoft.Data.SqlClient.SNI
(dependencia de .NET Framework) y Microsoft.Data.SqlClient.SNI.runtime
(dependencia de .NET Core/Standard) se han actualizado a v3.0.0-preview1.21104.2
. El seguimiento de eventos en SNI.dll ya no se habilita mediante una aplicación cliente. Basta con la suscripción de una sesión al proveedor Microsoft.Data.SqlClient.EventSource mediante herramientas como xperf
o perfview
. Para obtener más información, vea Compatibilidad con el seguimiento de eventos en SNI nativo.
Habilitación del comportamiento null de la versión de fila
SqlDataReader
devuelve un valor DBNull
en lugar de un byte[]
vacío. Para habilitar el comportamiento heredado, debe habilitar el siguiente modificador de AppContext al iniciar la aplicación: "Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior" .
Compatibilidad con la autenticación predeterminada de Microsoft Entra
Nota:
Aunque Microsoft Entra ID es el nuevo nombre de Azure Active Directory (Azure AD), para evitar interrumpir los entornos existentes, Azure AD sigue estando en algunos elementos codificados de forma rígida como campos de interfaz de usuario, proveedores de conexiones, códigos de error y cmdlets. En este artículo, los dos nombres son intercambiables.
Esta solicitud de incorporación de cambios introduce un nuevo método de autenticación SQL: Valor predeterminado de Active Directory. Este modo de autenticación aumenta las posibilidades de autenticación del usuario con Microsoft Entra ID, ya que amplía las soluciones de inicio de sesión al entorno de cliente, Visual Studio Code, Visual Studio, la CLI de Azure, etc.
Con este modo de autenticación, el controlador adquiere un token al pasar "DefaultAzureCredential" desde la biblioteca Azure Identity para adquirir un token de acceso. Este modo intenta usar estos tipos de credenciales para adquirir un token de acceso en el orden siguiente:
- EnvironmentCredential
- Habilita la autenticación para Microsoft Entra ID mediante el cliente y el secreto, o el nombre de usuario y la contraseña, y los detalles configurados en las siguientes variables de entorno: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_CLIENT_CERTIFICATE_PATH, AZURE_USERNAME y AZURE_PASSWORD (más información)
- ManagedIdentityCredential
- Intenta la autenticación de Microsoft Entra ID mediante una identidad administrada que se ha asignado al entorno de implementación. El valor "Id. de cliente" de la "identidad administrada asignada por el usuario" se lee desde la propiedad de conexión "Id. de usuario".
- SharedTokenCacheCredential
- Realiza la autenticación mediante tokens en la caché local compartida entre aplicaciones de Microsoft.
- VisualStudioCredential
- Permite la autenticación con Microsoft Entra ID mediante los datos de Visual Studio
- VisualStudioCodeCredential
- Permite la autenticación con Microsoft Entra ID mediante los datos de Visual Studio Code.
- AzureCliCredential
- Habilita la autenticación con Microsoft Entra ID mediante la CLI de Azure para obtener un token de acceso.
InteractiveBrowserCredential está deshabilitado en la implementación del controlador de "Valor predeterminado de Active Directory", y "Active Directory interactivo" es la única opción disponible para adquirir un token mediante MFA o la autenticación interactiva.*
Por el momento, no hay más opciones de personalización disponibles.
Mejoras en el registro de proveedores personalizados de almacén de claves maestras
Microsoft.Data.SqlClient ahora permite controlar mejor dónde se puede acceder a los proveedores de almacén de claves maestras en una aplicación, con el fin de admitir mejor las aplicaciones multiinquilino y su uso del cifrado y descifrado de columnas. Se han introducido las API siguientes para permitir el registro de proveedores personalizados de almacén de claves maestras en instancias de SqlConnection
y SqlCommand
:
public class SqlConnection
{
public void RegisterColumnEncryptionKeyStoreProvidersOnConnection(IDictionary<string, SqlColumnEncryptionKeyStoreProvider> customProviders)
}
public class SqlCommand
{
public void RegisterColumnEncryptionKeyStoreProvidersOnCommand(IDictionary<string, SqlColumnEncryptionKeyStoreProvider> customProviders)
}
Se sigue admitiendo la API estática en SqlConnection
(SqlConnection.RegisterColumnEncryptionKeyStoreProviders
) para registrar globalmente proveedores personalizados de almacén de claves maestras. La caché de claves de cifrado de columnas mantenida globalmente solo se aplica a los proveedores registrados globalmente.
Precedencia del registro de proveedores de almacén de claves maestras de columna
Los proveedores integrados de almacén de claves maestras de columna que están disponibles para el almacén de certificados de Windows, el almacén de CNG y CSP están registrados previamente. No se debe registrar ningún proveedor en las instancias de conexión o de comando si se necesita uno de los proveedores integrados de almacén de claves maestras de columna.
Los proveedores personalizados de almacén de claves maestras se pueden registrar con el controlador en tres capas diferentes. El nivel global es el que se muestra actualmente. Los nuevos registros de nivel por conexión y por comando están vacíos inicialmente y se pueden establecer más de una vez.
Las precedencias de los tres registros son las siguientes:
- El registro por comando se comprueba si no está vacío.
- Si el registro por comando está vacío, el registro por conexión se comprueba si no está vacío.
- Si el registro por conexión está vacío, se comprueba el registro global.
Una vez que se encuentre un proveedor de almacén de claves en el nivel de registro, el controlador NO vuelve a los demás registros para buscar un proveedor. Si los proveedores están registrados, pero no se encuentra el proveedor adecuado en un nivel, se produce una excepción que contiene únicamente los proveedores registrados en el registro comprobado.
Precedencia de la caché de claves de cifrado de columnas
El controlador no almacena en caché las claves de cifrado de columna (CEK) de los proveedores personalizados de almacén de claves registrados con las nuevas API de nivel de instancia. Los proveedores de almacén de claves deben implementar su propia memoria caché para aumentar el rendimiento. El controlador deshabilita esta caché local de claves de cifrado de columna implementadas por los proveedores personalizados de almacén de claves si la instancia del proveedor de almacén de claves está registrada en el controlador en el nivel global.
También se ha introducido una nueva API en la clase base SqlColumnEncryptionKeyStoreProvider
para establecer el período de vida de la caché:
public abstract class SqlColumnEncryptionKeyStoreProvider
{
// The default value of Column Encryption Key Cache Time to Live is 0.
// Provider's local cache is disabled for globally registered providers.
// Custom key store provider implementation must include column encryption key cache to provide caching support to locally registered providers.
public virtual TimeSpan? ColumnEncryptionKeyCacheTtl { get; set; } = new TimeSpan(0);
}
Preferencia de dirección IP
Se ha introducido una nueva propiedad de conexión IPAddressPreference
para indicar la preferencia de familia de direcciones IP al controlador al establecer conexiones TCP. Si Transparent Network IP Resolution
(en .NET Framework) o Multi Subnet Failover
se establecen en true
, esta configuración no tiene ningún efecto. Existen tres valores aceptados para esta propiedad:
IPv4First
- Este es el valor predeterminado. El controlador usa primero direcciones IPv4 resueltas. Si no es posible conectarse correctamente a ninguna de ellas, prueba con direcciones IPv6 resueltas.
IPv6First
- El controlador usa primero direcciones IPv6 resueltas. Si no es posible conectarse correctamente a ninguna de ellas, prueba con direcciones IPv4 resueltas.
UsePlatformDefault
- El controlador prueba las direcciones IP en el orden recibido en la respuesta de resolución DNS.
Compatibilidad con la plataforma de destino 3.0
- .NET Framework 4.6.1+ (Windows x86, Windows x64)
- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
Notas de la versión de Microsoft.Data.SqlClient 2.1
Las notas completas de la versión, incluidas las dependencias, están disponibles en el repositorio de GitHub: Notas de la versión 2.1.
Nuevas características de la versión 2.1
Compatibilidad entre plataformas para Always Encrypted
Microsoft.Data.SqlClient v2.1 amplía la compatibilidad con Always Encrypted en las siguientes plataformas:
Compatibilidad con Always Encrypted | Compatibilidad de Always Encrypted con enclaves seguros | Versión de .NET Framework de destino | Microsoft.Data.SqlClient Version | Sistema operativo |
---|---|---|---|---|
Sí | Sí | .NET Framework 4.6+ | 1.1.0 | Windows |
Sí | Sí | .NET Core 2.1+ | 2.1.0+1 | Windows, Linux, macOS |
Yes | No2 | .NET Standard 2.0 | 2.1.0+ | Windows, Linux, macOS |
Sí | Sí | .NET Standard 2.1+ | 2.1.0+ | Windows, Linux, macOS |
Nota
1 Antes de la versión 2.1 de Microsoft.Data.SqlClient, Always Encrypted solo se admite en Windows. 2 Always Encrypted con enclaves seguros no se admite en .NET Standard 2.0.
Autenticación de flujo de código de los dispositivos de Microsoft Entra
Microsoft.Data.SqlClient v2.1 proporciona compatibilidad para la autenticación "flujo de código de dispositivo" con MSAL.NET. Documentación de referencia: Flujo de concesión de autorización de dispositivo de OAuth 2.0
Ejemplo de cadena de conexión:
Server=<server>.database.windows.net; Authentication=Active Directory Device Code Flow; Database=Northwind;Encrypt=True
La siguiente API permite personalizar el mecanismo de devolución de llamada del flujo de código del dispositivo:
public class ActiveDirectoryAuthenticationProvider
{
// For .NET Framework, .NET Core and .NET Standard targeted applications
public void SetDeviceCodeFlowCallback(Func<DeviceCodeResult, Task> deviceCodeFlowCallbackMethod)
}
Autenticación de identidad administrada de Microsoft Entra
Microsoft.Data.SqlClient v2.1 incluye compatibilidad con la autenticación de Microsoft Entra mediante identidades administradas.
Se admiten las siguientes palabras clave de modo de autenticación:
- Identidad administrada de Active Directory
- MSI de Active Directory (para la compatibilidad entre controladores de MS SQL)
Ejemplos de cadena de conexión:
// For System Assigned Managed Identity
"Server={serverURL}; Authentication=Active Directory MSI; Encrypt=True; Initial Catalog={db};"
// For System Assigned Managed Identity
"Server={serverURL}; Authentication=Active Directory Managed Identity; Initial Catalog={db};"
// For User Assigned Managed Identity
"Server={serverURL}; Authentication=Active Directory MSI; Encrypt=True; User Id={ObjectIdOfManagedIdentity}; Initial Catalog={db};"
// For User Assigned Managed Identity
"Server={serverURL}; Authentication=Active Directory Managed Identity; Encrypt=True; User Id={ObjectIdOfManagedIdentity}; Initial Catalog={db};"
Mejoras en la autenticación interactiva de Microsoft Entra
Microsoft.Data.SqlClient v2.1 agrega las siguientes API para personalizar la experiencia de autenticación de Microsoft Entra interactivo:
public class ActiveDirectoryAuthenticationProvider
{
// For .NET Framework targeted applications only
public void SetIWin32WindowFunc(Func<IWin32Window> iWin32WindowFunc);
// For .NET Standard targeted applications only
public void SetParentActivityOrWindowFunc(Func<object> parentActivityOrWindowFunc);
// For .NET Framework, .NET Core and .NET Standard targeted applications
public void SetAcquireAuthorizationCodeAsyncCallback(Func<Uri, Uri, CancellationToken, Task<Uri>> acquireAuthorizationCodeAsyncCallback);
// For .NET Framework, .NET Core and .NET Standard targeted applications
public void ClearUserTokenCache();
}
Sección de configuración SqlClientAuthenticationProviders
Microsoft.Data.SqlClient v2.1 presenta una nueva sección de configuración, SqlClientAuthenticationProviders
(un clon de SqlAuthenticationProviders
existente). La sección de configuración existente, SqlAuthenticationProviders
, todavía se admite por compatibilidad con versiones anteriores cuando se define el tipo adecuado.
La nueva sección permite que los archivos de configuración de la aplicación contengan una sección SqlAuthenticationProviders para System.Data.SqlClient y una sección SqlClientAuthenticationProviders section para Microsoft.Data.SqlClient.
Autenticación de Microsoft Entra mediante un Id. de cliente de aplicación
Microsoft.Data.SqlClient v2.1 incluye compatibilidad para pasar un identificador de cliente de aplicación definido por el usuario a la Biblioteca de autenticación de Microsoft. El Id. de cliente de aplicación se usa al autenticarse con Microsoft Entra ID.
Se introdujeron las siguientes API nuevas:
Se ha introducido un nuevo constructor en ActiveDirectoryAuthenticationProvider:
[Se aplica a todas las plataformas de .NET (.NET Framework, .NET Core y .NET Standard)]public ActiveDirectoryAuthenticationProvider(string applicationClientId)
Uso:
string APP_CLIENT_ID = "<GUID>"; SqlAuthenticationProvider customAuthProvider = new ActiveDirectoryAuthenticationProvider(APP_CLIENT_ID); SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryInteractive, customAuthProvider); using (SqlConnection sqlConnection = new SqlConnection("<connection_string>") { sqlConnection.Open(); }
Se ha introducido una nueva propiedad de configuración en
SqlAuthenticationProviderConfigurationSection
ySqlClientAuthenticationProviderConfigurationSection
:
[Se aplica a .NET Framework and .NET Core]internal class SqlAuthenticationProviderConfigurationSection : ConfigurationSection { ... [ConfigurationProperty("applicationClientId", IsRequired = false)] public string ApplicationClientId => this["applicationClientId"] as string; } // Inheritance internal class SqlClientAuthenticationProviderConfigurationSection : SqlAuthenticationProviderConfigurationSection { ... }
Uso:
<configuration> <configSections> <section name="SqlClientAuthenticationProviders" type="Microsoft.Data.SqlClient.SqlClientAuthenticationProviderConfigurationSection, Microsoft.Data.SqlClient" /> </configSections> <SqlClientAuthenticationProviders applicationClientId ="<GUID>" /> </configuration> <!--or--> <configuration> <configSections> <section name="SqlAuthenticationProviders" type="Microsoft.Data.SqlClient.SqlAuthenticationProviderConfigurationSection, Microsoft.Data.SqlClient" /> </configSections> <SqlAuthenticationProviders applicationClientId ="<GUID>" /> </configuration>
Compatibilidad con la clasificación de datos v2
Microsoft.Data.SqlClient v2.1 incluye compatibilidad con la información de "rango de confidencialidad" de la clasificación de datos. Ahora están disponibles las siguientes API nuevas:
public class SensitivityClassification
{
public SensitivityRank SensitivityRank;
}
public class SensitivityProperty
{
public SensitivityRank SensitivityRank;
}
public enum SensitivityRank
{
NOT_DEFINED = -1,
NONE = 0,
LOW = 10,
MEDIUM = 20,
HIGH = 30,
CRITICAL = 40
}
Identificador de proceso de servidor para SqlConnection
activo
Microsoft.Data.SqlClient v2.1 introduce una nueva propiedad SqlConnection
, ServerProcessId
, en una conexión activa.
public class SqlConnection
{
// Returns the server process Id (SPID) of the active connection.
public int ServerProcessId;
}
Compatibilidad del registro de seguimiento en SNI nativo
Microsoft.Data.SqlClient v2.1 amplía la implementación de SqlClientEventSource
existente para habilitar el seguimiento de eventos en SNI.dll. Los eventos deben capturarse con una herramienta como Xperf.
El seguimiento se puede habilitar mediante el envío de un comando a SqlClientEventSource
como se muestra a continuación:
// Enables trace events:
EventSource.SendCommand(eventSource, (EventCommand)8192, null);
// Enables flow events:
EventSource.SendCommand(eventSource, (EventCommand)16384, null);
// Enables both trace and flow events:
EventSource.SendCommand(eventSource, (EventCommand)(8192 | 16384), null);
Propiedad de la cadena de conexión "Tiempo de espera del comando"
Microsoft.Data.SqlClient v2.1 introduce la propiedad de la cadena de conexión "Tiempo de espera del comando" para reemplazar el valor predeterminado de 30 segundos. El tiempo de espera para los comandos individuales se puede invalidar mediante la propiedad CommandTimeout
en SqlCommand.
Ejemplos de cadena de conexión:
"Server={serverURL}; Initial Catalog={db}; Encrypt=True; Integrated Security=true; Command Timeout=60"
Eliminación de símbolos de SNI nativo
Con Microsoft.Data.SqlClient v.2.1, hemos quitado los símbolos introducidos en v2.0.0 de NuGet Microsoft.Data.SqlClient.SNI.runtime a partir de la v2.1.1. Los símbolos públicos se publican ahora en el servidor de símbolos de Microsoft para herramientas como BinSkim que requieren acceso a símbolos públicos.
Vinculación de origen de símbolos de Microsoft.Data.SqlClient
A partir de Microsoft.Data.SqlClient v2.1, los símbolos de Microsoft.Data.SqlClient se vinculan por código fuente y se publican en el servidor de símbolos de Microsoft para una experiencia de depuración mejorada sin necesidad de descargar el código fuente.
Compatibilidad con la plataforma de destino 2.1
- .NET Framework 4.6+ (Windows x86, Windows x64)
- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
Notas de la versión de Microsoft.Data.SqlClient 2.0
Las notas completas de la versión, incluidas las dependencias, están disponibles en el repositorio de GitHub: Notas de la versión 2.0.
Cambios importantes en la versión 2.0
- El modificador de acceso de la interfaz del proveedor de enclave
SqlColumnEncryptionEnclaveProvider
ha cambiado depublic
ainternal
. - Las constantes de la clase
SqlClientMetaDataCollectionNames
se han actualizado para reflejar los cambios en SQL Server. - El controlador realiza ahora la validación del certificado de servidor cuando el servidor SQL Server de destino aplica el cifrado TLS, que es el valor predeterminado para las conexiones de Azure.
SqlDataReader.GetSchemaTable()
ahora devuelve un elementoDataTable
vacío en lugar denull
.- El controlador ahora realiza el redondeo de la escala decimal para que coincida con el comportamiento de SQL Server. Para obtener compatibilidad con versiones anteriores, el comportamiento anterior del truncamiento se puede habilitar mediante un modificador AppContext.
- En el caso de las aplicaciones de .NET Framework que consumen Microsoft.Data.SqlClient, los archivos SNI.dll descargados previamente en las carpetas
bin\x64
ybin\x86
ahora se denominanMicrosoft.Data.SqlClient.SNI.x64.dll
yMicrosoft.Data.SqlClient.SNI.x86.dll
, y se descargan en el directoriobin
. - Por coherencia, los sinónimos nuevos de la propiedad cadena de conexión reemplazan a las propiedades anteriores cuando se recupera la cadena de conexión de
SqlConnectionStringBuilder
. Más información
Nuevas características de la versión 2.0
En Microsoft.Data.SqlClient 2.0 se han incorporado las características nuevas siguientes.
Resistencia ante errores de DNS
Ahora, el controlador copia en caché las direcciones IP de todas las conexiones correctas a un punto de conexión de SQL Server que admite la característica. Si se produce un error de resolución de DNS durante un intento de conexión, el controlador intenta establecer una conexión mediante una dirección IP copiada en caché para ese servidor, si existe.
Seguimiento de EventSource
Esta versión permite la captura de registros de seguimiento de eventos para la depuración de aplicaciones. Para capturar estos eventos, las aplicaciones cliente deben escuchar eventos de la implementación de EventSource de SqlClient:
Microsoft.Data.SqlClient.EventSource
Para obtener más información, vea cómo habilitar el seguimiento de eventos en SqlClient.
Habilitación de redes administradas en Windows
Un nuevo modificador de AppContext "Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows" permite el uso de una implementación de SNI administrada en Windows con fines de prueba y depuración. Este modificador alterna el comportamiento del controlador para usar un SNI administrado en los proyectos de .NET Core 2.1+ y .NET Standard 2.0+ en Windows, eliminando todas las dependencias de las bibliotecas nativas para la biblioteca Microsoft.Data.SqlClient.
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true);
Vea Modificadores de AppContext en SqlClient para obtener una lista completa de los modificadores disponibles en el controlador.
Habilitación del comportamiento de truncamiento decimal
El controlador redondea la escala de datos decimal de forma predeterminada, tal y como lo hace SQL Server. Para obtener la compatibilidad con versiones anteriores, puede establecer el modificador de AppContext "Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal" en true.
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal", true);
Sinónimos nuevos de la propiedad de cadena de conexión
Se han agregado sinónimos nuevos para las siguientes propiedades de cadena de conexión existentes a fin de evitar la confusión de espaciado en torno a las propiedades con más de una palabra. Los nombres de propiedad antiguos siguen siendo compatibles con las versiones anteriores. Pero las nuevas propiedades de cadena de conexión ahora se incluyen al capturar la cadena de conexión de SqlConnectionStringBuilder.
Propiedad existente de cadena de conexión | Nuevo sinónimo |
---|---|
Intención de aplicaciones | Intención de aplicaciones |
ConnectRetryCount | Recuento de reintentos de conexión |
ConnectRetryInterval | Intervalo de reintentos de conexión |
PoolBlockingPeriod | Período de bloqueo del grupo |
MultipleActiveResultSets | Conjunto de resultados activo múltiple (MARS) |
MultiSubnetFailover | Conmutación por error de varias subredes |
TransparentNetworkIPResolution | Resolución de IP de red transparente |
TrustServerCertificate | TrustServerCertificate |
Propiedad RowsCopied de SqlBulkCopy
La propiedad RowsCopied proporciona acceso de solo lectura al número de filas que se han procesado en la operación de copia masiva en curso. Este valor no necesariamente tiene que ser igual al número final de filas agregadas a la tabla de destino.
Invalidaciones de apertura de la conexión
El comportamiento predeterminado de SqlConnection.Open() se puede invalidar para deshabilitar el retraso de diez segundos y los reintentos de conexión automática que desencadenan los errores transitorios.
using SqlConnection sqlConnection = new SqlConnection("Data Source=(local);Integrated Security=true;Initial Catalog=AdventureWorks;");
sqlConnection.Open(SqlConnectionOverrides.OpenWithoutRetry);
Nota
Tenga en cuenta que esta invalidación solo se puede aplicar a SqlConnection.Open() y no a SqlConnection.OpenAsync().
Compatibilidad con el nombre de usuario para el modo interactivo de Active Directory
Se puede especificar un nombre de usuario en la cadena de conexión cuando se usa el modo interactivo de autenticación de Microsoft Entra para .NET Framework y .NET Core
Establezca un nombre de usuario mediante la propiedad de cadena de conexión User ID o UID:
"Server=<server name>; Database=<db name>; Authentication=Active Directory Interactive; User Id=<username>;Encrypt=True;"
Sugerencias de orden para SqlBulkCopy
Se pueden proporcionar sugerencias de orden para mejorar el rendimiento de las operaciones de copia masiva en tablas con índices agrupados. Para obtener más información, vea la sección Operaciones de copia masiva.
Cambios de dependencia de SNI
Microsoft.Data.SqlClient (.NET Core y .NET Standard) en Windows ahora depende de Microsoft.Data.SqlClient.SNI.runtime, reemplazando la dependencia anterior en runtime.native.System.Data.SqlClient.SNI. La dependencia nueva agrega compatibilidad con la plataforma ARM junto con las plataformas ya admitidas ARM64, x64 y x86 en Windows.
Compatibilidad con la plataforma de destino 2.0
- .NET Framework 4.6+ (Windows x86, Windows x64)
- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
Notas de la versión de Microsoft.Data.SqlClient 1.1.0
Las notas completas de la versión, incluidas las dependencias, están disponibles en el repositorio de GitHub: Notas de la versión 1.1.
Nuevas características de la versión 1.1
Always Encrypted con enclaves seguros
Always Encrypted está disponible a partir de Microsoft SQL Server 2016. Los enclaves seguros están disponibles a partir de Microsoft SQL Server 2019. Para usar la característica de enclaves, las cadenas de conexión deben incluir el protocolo de atestación y la dirección URL de atestación necesarios. Por ejemplo:
"Attestation Protocol=HGS;Enclave Attestation Url=<attestation_url_for_HGS>"
Para más información, consulte:
- Compatibilidad de SqlClient para Always Encrypted
- Tutorial: Desarrollo de una aplicación de .NET mediante Always Encrypted con enclaves seguros
Compatibilidad con la plataforma de destino 1.1
- .NET Framework 4.6+ (Windows x86, Windows x64)
- .NET Core 2.1+ (Windows x86, Windows x64, Linux, macOS)
- .NET Standard 2.0+ (Windows x86, Windows x64, Linux, macOS)
Notas de la versión de Microsoft.Data.SqlClient 1.0
La versión inicial del espacio de nombres Microsoft.Data.SqlClient ofrece más funcionalidades que el espacio de nombres System.Data.SqlClient existente.
Las notas completas de la versión, incluidas las dependencias, están disponibles en el repositorio de GitHub: Notas de la versión 1.0.
Nuevas características de la versión 1.0
Nuevas características de System.Data.SqlClient en .NET Framework 4.7.2
Clasificación de datos: disponible en Azure SQL Database y Microsoft SQL Server 2019.
Compatibilidad con UTF-8: disponible en Microsoft SQL Server 2019.
Nuevas características de System.Data.SqlClient en .NET Core 2.2
Clasificación de datos: disponible en Azure SQL Database y Microsoft SQL Server 2019.
Compatibilidad con UTF-8: disponible en Microsoft SQL Server 2019.
Autenticación: modo de autenticación de contraseña de Active Directory.
Clasificación de datos
La clasificación de datos proporciona un nuevo conjunto de API que exponen información de clasificación y confidencialidad de los datos de solo lectura de los objetos recuperados a través de SqlDataReader cuando el origen subyacente admite la característica y contiene metadatos de confidencialidad y clasificación de datos. Vea la aplicación de ejemplo en Detección y clasificación de datos en SqlClient.
public class SqlDataReader
{
public Microsoft.Data.SqlClient.DataClassification.SensitivityClassification SensitivityClassification
}
namespace Microsoft.Data.SqlClient.DataClassification
{
public class ColumnSensitivity
{
public System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.Data.SqlClient.DataClassification.SensitivityProperty> SensitivityProperties
}
public class InformationType
{
public string Id
public string Name
}
public class Label
{
public string Id
public string Name
}
public class SensitivityClassification
{
public System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.Data.SqlClient.DataClassification.ColumnSensitivity> ColumnSensitivities
public System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.Data.SqlClient.DataClassification.InformationType> InformationTypes
public System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.Data.SqlClient.DataClassification.Label> Labels
}
public class SensitivityProperty
{
public Microsoft.Data.SqlClient.DataClassification.InformationType InformationType
public Microsoft.Data.SqlClient.DataClassification.Label Label
}
}
Compatibilidad con UTF-8
La compatibilidad con UTF-8 no requiere hacer ningún cambio en el código de la aplicación. Estos cambios de SqlClient optimizan la comunicación entre el cliente y el servidor cuando el servidor admite UTF-8 y la intercalación de columna subyacente es UTF-8. Consulte la sección UTF-8 en Novedades de SQL Server 2019.
Always Encrypted con enclaves seguros
En general, la documentación existente que usa System.Data.SqlClient en .NET Framework y los proveedores de almacenamiento de claves maestras de columna integradas ahora deben trabajar también con .NET Core.
Desarrollar con Always Encrypted con el proveedor de datos .NET Framework
Authentication
Se pueden especificar diferentes modos de autenticación mediante la opción de cadena de conexión Autenticación. Para obtener más información, consulte la documentación de SqlAuthenticationMethod.
Nota
Los proveedores de almacén de claves personalizados, como el proveedor de Azure Key Vault, deberán actualizarse para admitir Microsoft.Data.SqlClient. Del mismo modo, también será necesario actualizar los proveedores de enclaves para que sean compatibles con Microsoft.Data.SqlClient. Always Encrypted solo se admite en los destinos de .NET Framework y .NET Core. No se admite con .NET Standard ya que en .NET Standard faltan algunas dependencias de cifrado.
Compatibilidad con la plataforma de destino 1.0
- .NET Framework 4.6+ (Windows x86, Windows x64)
- .NET Core 2.1+ (Windows x86, Windows x64, Linux, macOS)
- .NET Standard 2.0+ (Windows x86, Windows x64, Linux, macOS)