Introdução ao namespace Microsoft.Data.SqlClient

Baixar ADO.NET

O namespace Microsoft.Data.SqlClient é essencialmente uma nova versão do namespace System.Data.SqlClient. Microsoft.Data.SqlClient geralmente mantém a mesma API e compatibilidade com o System.Data.SqlClient. A migração de System.Data.SqlClient para Microsoft.Data.SqlClient é simples para a maioria dos aplicativos. Adicione uma dependência do NuGet ao Microsoft.Data.SqlClient e atualize referências e instruções using para o Microsoft.Data.SqlClient.

Há algumas diferenças nas APIs menos usadas em comparação com System.Data.SqlClient que podem afetar alguns aplicativos. Para conhecer essas diferenças, consulte o roteiro de portabilidade, que é bastante útil.

Referência de API

Os detalhes da API Microsoft.Data.SqlClient podem ser encontrados no Navegador de API do .NET.

Notas sobre a versão do Microsoft.Data.SqlClient 5.2

Novas funcionalidades na versão 5.2

  • Adição de suporte ao SqlDiagnosticListener no .NET Standard. #1931
  • Adição de nova propriedade RowsCopied64 a SqlBulkCopy. #2004Leia mais
  • Adição de uma nova API do AccessTokenCallBack ao SqlConnection. #1260Leia mais
  • Adição de suporte à opção SuperSocketNetLib do Registro para criptografar no .NET no Windows. #2047
  • Adição de suporte a SqlBatch no .NET 6+ #1825, #2223Leia mais
  • Adição de suporte à autenticação de identidade de cargas de trabalho #2159, #2264
  • Adição de suporte à localização no .NET #2210
  • Adição de suporte à ordenação Georgian #2194
  • Adição de suporte a sistemas Big Endian #2170
  • Adição de suporte ao .NET 8 #2230
  • Adição de versão explícita para as principais dependências da versão do .NET em System.Runtime.Caching 8.0.0, System.Configuration.ConfigurationManager 8.0.0 e System.Diagnostics.DiagnosticSource 8.0.0 #2303
  • Adição da capacidade de gerar símbolos de depuração em um arquivo de pacote separado #2137

Adição da nova propriedade RowsCopied64 a SqlBulkCopy

SqlBulkCopy possui uma nova propriedade RowsCopied64 que oferece suporte a tipos de valor long.

Observe que o comportamento SqlBulkCopy.RowsCopied existente permanece inalterado. Quando o valor excede int.MaxValue, RowsCopied pode retornar um número negativo.

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

Adição de nova propriedade AccessTokenCallBack a SqlConnection

SqlConnection oferece suporte à autenticação TokenCredential introduzindo uma nova propriedade AccessTokenCallBack como um representante Func<SqlAuthenticationParameters, CancellationToken,Task<SqlAuthenticationToken>> para retornar um token de acesso de autenticação federada.

Exemplo de uso:

    using Microsoft.Data.SqlClient;
    using Azure.Identity;

    const string defaultScopeSuffix = "/.default";
    string connectionString = GetConnectionString();
    using SqlConnection connection = new SqlConnection(connectionString);
    
    connection.AccessTokenCallback = async (authParams, cancellationToken) =>
    {
        var cred = new DefaultAzureCredential();
        string scope = authParams.Resource.EndsWith(defaultScopeSuffix) ? authParams.Resource : authParams.Resource + defaultScopeSuffix;
        AccessToken token = await cred.GetTokenAsync(new TokenRequestContext(new[] { 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

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

Suporte à 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)

As notas sobre a versão completas, incluindo dependências, estão disponíveis no Repositório do GitHub: Notas sobre a versão 5.2.

Alterações interruptivas na versão 5.1

Novos recursos na versão 5.1

  • Adicionado suporte para DateOnly e TimeOnly para o valor SqlParameter e GetFieldValue. Nº 1813
  • Adicionado suporte para TLS 1.3 para .NET Core e SNI nativo. Nº 1821
  • Foi adicionada a configuração ServerCertificate para Encrypt=Mandatory ou Encrypt=Strict. Nº 1822Leia mais
  • Adicionado suporte ao Windows ARM64 ao direcionar o .NET Framework. Nº 1828

Certificado de servidor

O valor padrão da configuração de conexão ServerCertificate é uma cadeia de caracteres vazia. Quando Encrypt é definido como Mandatory ou Strict, ServerCertificate pode ser usado para especificar um caminho no sistema de arquivos para um arquivo de certificado que corresponda ao certificado TLS/SSL do servidor. O certificado especificado precisa ser uma correspondência exata para ser válido. Os formatos de certificado aceitos são PEM, DER e CER. Aqui está um exemplo de uso:

"Data Source=...;Encrypt=Strict;ServerCertificate=C:\\certificates\\server.cer"

Suporte à plataforma de destino 5.1

  • .NET Framework 4.6.2+ (Windows x86, Windows x64)
  • .NET 6.0+ (Windows x86, Windows x64, Windows ARM64, Microsoft Azure Resource Manager, Linux, macOS)
  • .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)

As notas de versão completas, incluindo dependências, estão disponíveis no Repositório do GitHub: Notas de versão 5.1.

Notas sobre a versão do Microsoft.Data.SqlClient 5.0

Alterações interruptivas da versão 5.0

  • Foi removido o suporte para o .NET Framework 4.6.1 #1574
  • Adicionada uma dependência ao pacote Microsoft.SqlServer.Server. Essa nova dependência poderá causar conflitos de namespace se o aplicativo fizer referência a esse namespace e ainda tiver referências de pacote (diretas ou indiretas) ao System.Data.SqlClient do .NET Core.
  • Retiradas classes do namespace Microsoft.Data.SqlClient.Server, que foram substituídas por tipos com suporte do pacote Microsoft.SqlServer.Server.#1585. As classes e enumerações afetadas são:
    • 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
    • (enumeração) Microsoft.Data.SqlClient.Server.DataAccessKind -> Microsoft.SqlServer.Server.DataAccessKind
    • (enumeração) Microsoft.Data.SqlClient.Server.Format -> Microsoft.SqlServer.Server.Format
    • (enumeração) Microsoft.Data.SqlClient.Server.SystemDataAccessKind -> Microsoft.SqlServer.Server.SystemDataAccessKind

Novas funcionalidades na versão 5.0

  • Adicionado suporte para TDS8. Para usar o TDS 8, os usuários devem especificar Encrypt=Strict na cadeia de conexão. #1608Leia mais
  • Adicionado suporte para especificar o SPN do Servidor e o SPN do Servidor de Failover na conexão. #1607Leia mais
  • Adicionado suporte para aliases ao direcionar o .NET Core no Windows. #1588Leia mais
  • Adicionado SqlDataSourceEnumerator. #1430Leia mais
  • Foi adicionada uma nova opção AppContext para suprimir avisos TLS inseguros. #1457Leia mais

Segurança aprimorada do TDS 8

Para usar o TDS 8, especifique Encrypt=Strict na cadeia de conexão. O modo estrito desabilita o TrustServerCertificate (sempre tratado como False no modo Estrito). HostNameInCertificate foi adicionado para ajudar alguns cenários de modo estrito. O TDS 8 começa e continua toda a comunicação do servidor dentro de uma conexão TLS criptografada e segura.

Novos valores de criptografia foram adicionados para esclarecer o comportamento de criptografia de conexão. Encrypt=Mandatory é equivalente a Encrypt=True e criptografa conexões durante a negociação de conexão TDS. Encrypt=Optional é equivalente a Encrypt=False e apenas criptografará a conexão se o servidor informar ao cliente que a criptografia é necessária durante a negociação de conexão TDS.

Para obter mais informações sobre como criptografar conexões com o servidor, confira Criptografia e validação de certificado.

HostNameInCertificate pode ser especificado na cadeia de conexão ao usar aliases para se conectar com criptografia a um servidor que tenha um certificado de servidor com um nome ou nome de assunto alternativo, diferente do nome usado pelo cliente para identificar o servidor (aliases DNS, por exemplo). Exemplo de uso: HostNameInCertificate=MyDnsAliasName

SPN do servidor

Ao se conectar em um ambiente que tenha topografia de domínio/floresta exclusiva, você pode ter requisitos específicos para SPNs de servidor. As configurações de cadeia de conexão ServerSPN/Server SPN e FailoverServerSPN/Failover Server SPN podem ser usadas para substituir os SPNs de servidor gerados automaticamente usados durante a autenticação integrada em um ambiente de domínio

Suporte para aliases SQL

Os usuários podem configurar aliases usando o SQL Server Configuration Manager. Esses aliases são armazenados no Registro do Windows e já têm suporte ao direcionar .NET Framework. Esta versão traz suporte para aliases ao direcionar o .NET ou o .NET Core no Windows.

Suporte ao enumerador de fonte de dados SQL

Fornece um mecanismo para enumerar todas as instâncias disponíveis do SQL Server na rede 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("============================");  
    }  
  }  

Suprimir avisos TLS inseguros

Um aviso de segurança será gerado no console se a versão TLS menor que 1.2 for usada para negociar com o servidor. Esse aviso pode ser suprimido na conexão SQL enquanto Encrypt = false habilitando a seguinte opção AppContext na inicialização do aplicativo:

Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning

Suporte à 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)

As notas sobre a versão completas, incluindo dependências, estão disponíveis no Repositório do GitHub: Notas sobre a versão 5.0.

Notas sobre a versão do Microsoft.Data.SqlClient 4.1

As notas sobre a versão completas, incluindo dependências, estão disponíveis no Repositório GitHub: Notas sobre a versão 4.1.

Novos recursos na versão 4.1

Introduzir Protocolo de Atestado None

Um novo protocolo de atestado chamado None será permitido na cadeia de conexão. Esse protocolo permite que os usuários renunciem ao atestado de enclave para seguintes enclaves VBS. Quando esse protocolo é definido, a propriedade de URL de atestado enclave é opcional.

Exemplo de cadeia de conexão:

//Attestation protocol NONE with no URL
"Data Source = {server}; Initial Catalog = {db}; Column Encryption Setting = Enabled; Attestation Protocol = None;"

Suporte à 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 sobre a versão do Microsoft.Data.SqlClient 4.0

As notas sobre a versão completas, incluindo dependências, estão disponíveis no Repositório do GitHub: Notas sobre a versão 4.0.

Alterações interruptivas da versão 4.0

  • EncryptPropriedade da cadeia de conexãotrue alterada como padrão. #1210Leia mais
  • O driver agora gera a SqlException substituindo AggregateException para os modos de autenticação do Active Directory. #1213
  • Descartada a propriedade de conexão Asynchronous Processing obsoleta de .NET Framework. #1148
  • Remoção da alternância de segurança Configurable Retry Logic. #1254Leia mais
  • Suporte removido para .NET Core 2.1 #1272
  • [.NET Framework] A exceção não será lançada se uma ID de usuário for fornecida na cadeia de conexão ao usar a Active Directory Integratedautenticação nº 1359

Novos recursos na versão 4.0

Criptografar o valor padrão definido como true

O valor padrão da configuração de conexão Encrypt foi alterado de false para true. Com o uso crescente de bancos de dados em nuvem e a necessidade de garantir que essas conexões sejam seguras, é hora dessa alteração interruptiva de compatibilidade com versões anteriores.

Verificar se as conexões falham quando a criptografia é necessária

Em cenários em que as bibliotecas de criptografia do cliente estavam desabilitadas ou indisponíveis, era possível fazer conexões não criptografadas quando a criptografia estava definida como true ou o servidor exigia criptografia.

Alternância de contexto do aplicativo para usar protocolos padrão do sistema

O driver não dá suporte a TLS 1.3; portanto, ele foi removido da lista de protocolos com suporte por padrão. Os usuários podem voltar para forçar o uso dos protocolos de cliente do sistema operacional, habilitando a seguinte alternância de contexto do aplicativo:

Switch.Microsoft.Data.SqlClient.UseSystemDefaultSecureProtocols

Habilitar a associação de parâmetro otimizada

O Microsoft.Data.SqlClient introduz uma nova APISqlCommand, EnableOptimizedParameterBinding para melhorar o desempenho de consultas com um grande número de parâmetros. Essa propriedade fica desabilitada por padrão. Quando definida como true, os nomes de parâmetros não são enviados para a instância do SQL Server quando o comando é executado.

public class SqlCommand
{
    public bool EnableOptimizedParameterBinding { get; set; }
}

Remover alternância de segurança de lógica de repetição configurável

A alternância de contexto do aplicativo "Switch.Microsoft.Data.SqlClient.EnableRetryLogic" não é mais necessária para usar o recurso lógico de repetição configurável. Agora há suporte para o recurso na produção. O comportamento padrão do recurso continua sendo uma política de não repetição, que os aplicativos cliente precisam substituir para permitir novas tentativas.

Suporte à instância compartilhada SqlLocalDb

Agora há suporte para as instâncias compartilhadas SqlLocalDb ao usar o SNI gerenciado.

  • Cenários possíveis:
    • (localdb)\. (conecta-se à instância padrão do SqlLocalDb)
    • (localdb)\<named instance>
    • (localdb)\.\<shared instance name> (*suporte recém-adicionado)

GetFieldValueAsync<T> e GetFieldValue<T> dá suporte a tipos XmlReader, TextReader, Stream

Os tipos XmlReader, TextReader, Stream agora têm suporte ao usar GetFieldValueAsync<T> e GetFieldValue<T>.

Exemplo 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
                }
            }
        }
    }
}

Suporte à 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 sobre a versão do Microsoft.Data.SqlClient 3.0

As notas sobre a versão completas, incluindo dependências, estão disponíveis no Repositório do GitHub: Notas sobre a versão 3.0.

Alterações interruptivas da versão 3.0

  • A versão mínima do .NET Framework com suporte foi aumentada para v4.6.1. Não há mais suporte para o .NET Framework v4.6.0. #899
  • A propriedade de conexão User Id agora exige Client Id em vez de Object Id para a Identidade gerenciada atribuída pelo usuário#1010Leia mais
  • O SqlDataReader agora retorna um valor DBNull em vez de um byte[] vazio. O comportamento herdado pode ser habilitado pela configuração do comutador AppContextSwitch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior#998Leia mais

Novos recursos da versão 3.0

Lógica de repetição configurável

Esse novo recurso introduz o suporte configurável para aplicativos cliente tentarem novamente em erros "transitórios" ou "passíveis". A configuração pode ser feita por meio de arquivos de configuração de código ou de aplicativo e as operações de repetição podem ser aplicadas para abrir uma conexão ou executar um comando. Esse recurso está desabilitado por padrão e está em versão prévia no momento. Para habilitar esse suporte, os aplicativos cliente devem ativar o seguinte comutador de segurança:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.EnableRetryLogic", true);

Quando o comutador .NET AppContext estiver habilitado, uma política lógica de repetição poderá ser definida para SqlConnection e SqlCommand de maneira independente ou em conjunto com várias opções de personalização.

Novas APIs públicas são introduzidas no SqlConnection e SqlCommand para o registro de uma implementação SqlRetryLogicBaseProvider personalizada:

public SqlConnection
{
    public SqlRetryLogicBaseProvider RetryLogicProvider;
}

public SqlCommand
{
    public SqlRetryLogicBaseProvider RetryLogicProvider;
}

Exemplos de uso de API podem ser encontrados aqui:

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

Novas seções de configuração também foram introduzidas para fazer o mesmo registro de arquivos de configuração sem precisar modificar o 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"/>

Veja abaixo exemplo simples de como usar as novas seções de configuração em arquivos de configuração:

<?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, os aplicativos podem implementar o próprio provedor da classe base do SqlRetryLogicBaseProvider e registrá-lo com SqlConnection/SqlCommand.

Contadores de eventos

Os seguintes contadores agora estão disponíveis para aplicativos destinados ao .NET Core 3.1+ e ao .NET Standard 2.1+:

Nome Nome de exibição Descrição
active-hard-connections Conexões ativas reais feitas para servidores atualmente O número de conexões atualmente abertas para servidores de banco de dados.
hard-connects Taxa de conexão real para servidores O número de conexões por segundo sendo abertas para servidores de banco de dados.
hard-disconnects Taxa de desconexão real de servidores O número de desconexões por segundo sendo feitas com servidores de banco de dados.
active-soft-connects Conexões ativas recuperadas do pool de conexão O número de conexões já abertas sendo consumidas do pool de conexão.
soft-connects Taxa de conexões recuperadas do pool de conexão O número de conexões por segundo sendo consumidas do pool de conexão.
soft-disconnects Taxa de conexões retornadas ao pool de conexão O número de conexões por segundo sendo retornadas ao pool de conexão.
number-of-non-pooled-connections Número de conexões que não estão utilizando o pool de conexão O número de conexões ativas que não estão no pool.
number-of-pooled-connections Número de conexões gerenciadas pelo pool de conexão O número de conexões ativas sendo gerenciadas pela infraestrutura de pooling de conexão.
number-of-active-connection-pool-groups Número de cadeias de conexão exclusivas ativas O número de grupos de pools de conexões ativos e exclusivos. Esse contador é baseado no número de cadeias de conexão exclusivas encontradas no AppDomain.
number-of-inactive-connection-pool-groups Número de cadeias de conexão exclusivas aguardando remoção O número de grupos de pools de conexão exclusivos marcados para remoção. Esse contador é baseado no número de cadeias de conexão exclusivas encontradas no AppDomain.
number-of-active-connection-pools Número de pools de conexão ativos O número total de pools de conexão.
number-of-inactive-connection-pools Número de pools de conexão inativos O número de pools de conexão inativos sem atividade recente e aguardando para serem descartados.
number-of-active-connections Quantidade de conexões ativas O número de conexões ativas atualmente em uso.
number-of-free-connections Número de conexões prontas no pool de conexão O número de conexões abertas disponíveis para uso nos pools de conexão.
number-of-stasis-connections Número de conexões que estão aguardando para serem prontas O número de conexões que estão aguardando a conclusão de uma ação e que não estão disponíveis para uso pelo aplicativo.
number-of-reclaimed-connections Número de conexões recuperadas da GC O número de conexões recuperadas por meio da coleta de lixo em que Close ou Dispose não foram chamadas pelo aplicativo. Observação O não fechamento ou o não descarte explícitos das conexões afeta o desempenho.

Esses contadores podem ser usados com as ferramentas da CLI global do .NET Core dotnet-counters e dotnet-trace no Windows ou Linux e PerfView no Windows, usando Microsoft.Data.SqlClient.EventSource como o nome do provedor. Para obter mais informações, confira Recuperar valores do contador de eventos.

dotnet-counters monitor Microsoft.Data.SqlClient.EventSource -p
PerfView /onlyProviders=*Microsoft.Data.SqlClient.EventSource:EventCounterIntervalSec=1 collect

Introdução à dependência do Azure Identity

O Microsoft.Data.SqlClient agora depende da biblioteca do Azure.Identity para adquirir tokens para os modos de autenticação "MSI/Identidades Gerenciadas do Active Directory" e "Entidade de Serviço do Active Directory". Essa alteração traz as seguintes alterações para a área de superfície pública:

  • Alteração interruptiva
    A propriedade de conexão "ID de usuário" agora requer a "ID do cliente" em vez da "ID de objeto" para a "Identidade gerenciada atribuída pelo usuário".
  • API pública
    Nova propriedade pública somente leitura: SqlAuthenticationParameters.ConnectionTimeout
  • Dependência
    Azure.Identity v1.3.0

Aprimoramentos no rastreamento de eventos no SNI.dll

As versões Microsoft.Data.SqlClient.SNI (dependência do .NET Framework) e Microsoft.Data.SqlClient.SNI.runtime (dependência do .NET Core/Standard) foram atualizadas para v3.0.0-preview1.21104.2. O rastreamento de eventos em SNI.dll não é mais ativado por meio de um aplicativo cliente. Inscrever uma sessão no provedor Microsoft.Data.SqlClient.EventSource por meio de ferramentas, como xperf ou perfview é suficiente. Para obter mais informações, confira Suporte ao rastreamento de eventos no SNI nativo.

Habilitando o comportamento nulo da versão de linha

O SqlDataReader retorna um valor DBNull em vez de um byte[] vazio. Para habilitar o comportamento herdado, habilite o seguinte comutador AppContext na inicialização do aplicativo: "Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior"

A autenticação do Microsoft Entra dá suporte a:

Observação

Embora o Microsoft Entra ID seja o novo nome do Azure Active Directory (Azure AD), para evitar a interrupção de ambientes existentes, o Azure AD ainda permanecerá em alguns elementos codificados, como campos de interface do usuário, provedores de conexão, códigos de erro e cmdlets. Neste artigo, os dois nomes são intercambiáveis.

Essa PR apresenta um novo método de autenticação do SQL, o Padrão do Active Directory. Este modo de autenticação amplia as possibilidades de autenticação do usuário, estendendo soluções de logon para o ambiente do cliente, o Visual Studio Code, o Visual Studio, a CLI do Azure etc.

Com esse modo de autenticação, o driver obtém um token passando "DefaultAzureCredential" da biblioteca do Azure Identity para adquirir um token de acesso. Esse modo tenta usar esses tipos de credenciais para obter um token de acesso na seguinte ordem:

  • EnvironmentCredential
    • Permite executar uma autenticação no Microsoft Entra ID usando um cliente e um segredo ou um nome de usuário e uma senha. Os detalhes estão configurados nestas variáveis de ambiente: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_CLIENT_CERTIFICATE_PATH, AZURE_USERNAME, AZURE_PASSWORD (mais detalhes)
  • ManagedIdentityCredential
    • Tenta executar uma autenticação no Microsoft Entra ID usando uma identidade gerenciada que foi atribuída ao ambiente de implantação. É possível ler a "ID do cliente" da "Identidade Gerenciada Atribuída pelo Usuário" na Propriedade de conexão da "ID de usuário" .
  • SharedTokenCacheCredential
    • Executa uma autenticação usando tokens compartilhados entre aplicativos da Microsoft no cache local.
  • VisualStudioCredential
    • Habilita a autenticação com Microsoft Entra ID usando dados do Visual Studio
  • VisualStudioCodeCredential
    • Habilita a autenticação com o Microsoft Entra ID usando dados do Visual Studio Code.
  • AzureCliCredential
    • Habilita a autenticação com a ID do Microsoft Entra usando a CLI do Azure para obter um token de acesso.

A opção InteractiveBrowserCredential está desabilitada na implementação do driver do "Padrão do Active Directory", portanto o "Active Directory Interactive" é a única opção disponível para obter um token usando a autenticação MFA/Interativa.*

No momento, não há outras opções de personalização disponíveis.

Aprimoramentos no registro dos provedores de repositórios de chaves mestras personalizadas

O Microsoft.Data.SqlClient agora oferece mais controle de onde os provedores de repositórios de chaves mestras podem ser acessados em um aplicativo, para dar melhor suporte a aplicativos multilocatário e ao uso de criptografia/descriptografia de coluna. As seguintes APIs foram introduzidas para permitir o registro de provedores de repositórios de chaves mestras personalizadas em instâncias do SqlConnection e SqlCommand:

public class SqlConnection
{
    public void RegisterColumnEncryptionKeyStoreProvidersOnConnection(IDictionary<string, SqlColumnEncryptionKeyStoreProvider> customProviders)
}
public class SqlCommand 
{
    public void RegisterColumnEncryptionKeyStoreProvidersOnCommand(IDictionary<string, SqlColumnEncryptionKeyStoreProvider> customProviders)
}

A API estática em SqlConnection, SqlConnection.RegisterColumnEncryptionKeyStoreProviders, usada para registrar provedores de repositórios de chaves mestras personalizadas globalmente continua a ter suporte. O cache de chave de criptografia de coluna mantido globalmente só se aplica a provedores registrados globalmente.

Precedência de registro do provedor de repositórios de chaves mestras de coluna

Os provedores internos de repositórios de chaves mestras de coluna que estão disponíveis para o Repositório de Certificados do Windows, a CNG Store e a CSP estão pré-registrados. Nenhum provedor deverá ser registrado nas instâncias de conexão ou comando se um dos provedores internos de repositórios de chaves mestras de coluna for necessário.

Provedores de repositórios de chaves mestras personalizadas podem ser registrados com o driver em três camadas diferentes. O nível global é como está atualmente. Os novos registros por conexão e por nível de comando estão vazios inicialmente e podem ser configurados mais de uma vez.

As precedências dos três registros são as seguintes:

  • O registro por comando será verificado se não estiver vazio.
  • Se o registro por comando estiver vazio, o registro por conexão será verificado se não estiver vazio.
  • Se o registro por conexão estiver vazio, o registro global será verificado.

Uma vez que um provedor de repositórios de chaves for encontrado em um nível de registro, o driver NÃO fará fallback para os outros registros para pesquisar um provedor. Se os provedores forem registrados, mas o provedor adequado não for encontrado em um nível, uma exceção será lançada contendo apenas os provedores registrados no registro verificado.

Precedência de cache de chave de criptografia de coluna

O driver não armazena em cache as CEKs (chaves de criptografia de coluna) para provedores de armazenamento de chaves personalizados registrados usando as novas APIs em nível de instância. Os provedores de repositórios de chaves precisam implementar o próprio cache para melhorar o desempenho. O driver desabilitará o cache local de chaves de criptografia de coluna implementadas por provedores de armazenamento de chaves personalizados se a instância do provedor de armazenamento de chaves estiver registrada no driver em nível global.

Uma nova API também foi introduzida na classe base SqlColumnEncryptionKeyStoreProvider para definir a vida útil do cache:

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

Preferência de endereço IP

Uma nova propriedade de conexão IPAddressPreference foi introduzida para especificar a preferência da família de endereço IP para o driver ao estabelecer conexões TCP. Se Transparent Network IP Resolution (no .NET Framework) ou Multi Subnet Failover estiver definido como true, essa configuração não terá nenhum efeito. Veja abaixo os três valores aceitos para essa propriedade:

  • IPv4First

    • Este é o valor padrão. O driver usa endereços IPv4 resolvidos primeiro. Se nenhum deles puder ser conectado com sucesso, ele tentará endereços IPv6 resolvidos.
  • IPv6First

    • O driver usa endereços IPv6 resolvidos primeiro. Se nenhum deles puder ser conectado com sucesso, ele tentará endereços IPv4 resolvidos.
  • UsePlatformDefault

    • O driver tenta endereços IP na ordem recebida da resposta de resolução DNS.

Suporte à 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 sobre a versão do Microsoft.Data.SqlClient 2.1

As notas sobre a versão completas, incluindo dependências, estão disponíveis no Repositório do GitHub: Notas sobre a versão 2.1.

Novos recursos da versão 2.1

Suporte multiplataforma ao Always Encrypted

O Microsoft. Data.SqlClient v2.1 estende o suporte ao Always Encrypted nas seguintes plataformas:

Suporte ao Always Encrypted Suporte ao Always Encrypted com enclaves seguros Estrutura de Destino Versão do Microsoft.Data.SqlClient Sistema operacional
Sim Sim .NET Framework 4.6 ou versão posterior 1.1.0+ Windows
Sim Sim .NET Core 2.1+ 2.1.0+1 Windows, Linux, macOS
Sim Não2 .NET Standard 2.0 2.1.0+ Windows, Linux, macOS
Sim Sim .NET Standard 2.1+ 2.1.0+ Windows, Linux, macOS

Observação

1 Antes da versão v2.1 do Microsoft.Data.SqlClient, só há suporte para o Always Encrypted no Windows. 2 O Always Encrypted com enclaves seguros tem suporte apenas no .NET Standard 2.0.

Autenticação do dispositivo do Microsoft Entra (5:55)

O Microsoft.Data.SqlClient v 2.1 dá suporte à autenticação de "fluxo de código do dispositivo" com o MSAL.NET. Documentação de referência: Fluxo de concessão de autorização do dispositivo OAuth 2.0

Exemplo de cadeia de conexão:

Server=<server>.database.windows.net; Authentication=Active Directory Device Code Flow; Database=Northwind;Encrypt=True

A seguinte API permite a personalização do mecanismo de retorno de chamada do fluxo de código do dispositivo:

public class ActiveDirectoryAuthenticationProvider
{
    // For .NET Framework, .NET Core and .NET Standard targeted applications
    public void SetDeviceCodeFlowCallback(Func<DeviceCodeResult, Task> deviceCodeFlowCallbackMethod)
}

Autenticação de identidade gerenciada pelo Microsoft Entra

O Microsoft.Data.SqlClient v 2.1 apresenta o suporte para autenticação do Microsoft Entra ID usando identidades gerenciadas.

Há suporte para as seguintes palavras-chave de modo de autenticação:

  • Identidade gerenciada do Active Directory
  • MSI do Active Directory (para compatibilidade entre drivers do MS SQL)

Exemplos de cadeia de conexão:

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

Autenticação interativa do Microsoft Entra

O Microsoft.Data.SqlClient v2.1 adiciona as seguintes APIs para personalizar a experiência de autenticação "interativa do Active Directory":

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

Seção de configuração SqlClientAuthenticationProviders

O Microsoft.Data.SqlClient v2.1 introduz uma nova seção de configuração, SqlClientAuthenticationProviders (um clone da SqlAuthenticationProvidersexistente). A seção de configuração existente, SqlAuthenticationProviders, ainda tem suporte para compatibilidade com versões anteriores quando o tipo apropriado é definido.

A nova seção permite que os arquivos de configuração de aplicativo contenham uma seção SqlAuthenticationProviders para System.Data.SqlClient e uma seção SqlClientAuthenticationProviders para Microsoft.Data.SqlClient.

Autenticação do Microsoft Entra usando uma ID de cliente de aplicativo

O Microsoft.Data.SqlClient v2.1 introduz o suporte para transmitir uma ID do cliente do aplicativo definida pelo usuário à Biblioteca de Autenticação da Microsoft. A ID do Cliente do Aplicativo é usada ao autenticar com a ID do Microsoft Entra.

Introdução das seguintes novas APIs:

  1. Um novo construtor foi introduzido em ActiveDirectoryAuthenticationProvider:
    [Aplica-se a todas as plataformas .NET (.NET Framework, .NET Core e .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();
    }
    
  2. Uma nova propriedade de configuração foi introduzida em SqlAuthenticationProviderConfigurationSection e SqlClientAuthenticationProviderConfigurationSection:
    [Aplica-se a .NET Framework e .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>
    

Suporte para classificação de dados v2

O Microsoft.Data.SqlClient v2.1 apresenta suporte para informações de "classificação de confidencialidade" da classificação de dados. Agora estão disponíveis as seguintes novas APIs:

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
}

ID do processo do servidor para uma SqlConnection ativa

O Microsoft.Data.SqlClient v2.1 introduz uma nova propriedade SqlConnection, ServerProcessId, em uma conexão ativa.

public class SqlConnection
{
    // Returns the server process Id (SPID) of the active connection.
    public int ServerProcessId;
}

Suporte ao registro em log de rastreamento no SNI nativo

O Microsoft.Data.SqlClient v2.1 estende a implementação da SqlClientEventSource existente para habilitar o rastreamento de eventos em SNI.dll. Os eventos devem ser capturados usando uma ferramenta como XPerf.

O rastreamento pode ser habilitado enviando um comando SqlClientEventSource para conforme ilustrado:

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

Propriedade de cadeia de conexão "Tempo limite do comando"

O Microsoft.Data.SqlClient v2.1 apresenta a propriedade de cadeia de conexão "Tempo limite do comando" para substituir o padrão de 30 segundos. O tempo limite para comandos individuais pode ser substituído usando a propriedade CommandTimeout no SqlCommand.

Exemplos de cadeia de conexão:

"Server={serverURL}; Initial Catalog={db}; Encrypt=True; Integrated Security=true; Command Timeout=60"

Remoção de símbolos do SNI nativo

Com o Microsoft.Data.SqlClient v2.1, removemos os símbolos introduzidos na v2.0.0 do NuGet do Microsoft.Data.SqlClient.SNI.Runtime começando com a v2.1.1. Os símbolos públicos agora são publicados no servidor de símbolos da Microsoft para ferramentas como BinSkim que exigem acesso a símbolos públicos.

Vinculação à fonte de símbolos do Microsoft.Data.SqlClient

A partir do Microsoft.Data.SqlClient v2.1, os símbolos do Microsoft.Data.SqlClient são vinculados à fonte e publicados no servidor de símbolos da Microsoft para uma experiência de depuração avançada sem a necessidade de baixar o código-fonte.

Suporte à 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 sobre a versão do Microsoft.Data.SqlClient 2.0

As notas sobre a versão completas, incluindo dependências, estão disponíveis no Repositório do GitHub: Notas sobre a versão 2.0.

Alterações interruptivas da versão 2.0

  • O modificador de acesso para a interface do provedor de enclave SqlColumnEncryptionEnclaveProvider foi alterado de public para internal.
  • As constantes na classe SqlClientMetaDataCollectionNames foram atualizadas para refletir as alterações no SQL Server.
  • O driver agora executa a validação do certificado do servidor quando o SQL Server de destino impõe a criptografia TLS, que é o padrão para conexões do Azure.
  • SqlDataReader.GetSchemaTable() agora retorna uma DataTable vazia em vez de null.
  • O driver agora executa o arredondamento de escala decimal para corresponder ao comportamento do SQL Server. Para compatibilidade com versões anteriores, o comportamento anterior de truncamento pode ser habilitado usando um comutador AppContext.
  • Para aplicativos .NET Framework que consomem o Microsoft.Data.SqlClient, os arquivos SNI.dll, baixados anteriormente nas pastas bin\x64 e bin\x86, agora são chamados de Microsoft.Data.SqlClient.SNI.x64.dll e Microsoft.Data.SqlClient.SNI.x86.dll. Além disso, eles serão baixados no diretório bin.
  • Os novos sinônimos de propriedade de cadeia de conexão substituirão as propriedades antigas ao buscar uma cadeia de conexão de SqlConnectionStringBuilder para fins de consistência. Leia mais

Novos recursos da versão 2.0

Os novos recursos mostrados abaixo foram introduzidos no Microsoft.Data.SqlClient 2.0.

Resiliência de falha de DNS

O driver agora armazena em cache os endereços IP de todas as conexões bem-sucedidas a um ponto de extremidade do SQL Server que dá suporte ao recurso. Se ocorrer uma falha de resolução de DNS durante uma tentativa de conexão, o driver tentará estabelecer uma conexão usando um endereço IP armazenado em cache para esse servidor, se houver.

Rastreamento de EventSource

Esta versão introduz suporte para capturar logs de rastreamento de eventos para depuração de aplicativos. Para capturar esses eventos, os aplicativos cliente devem escutar eventos da implementação EventSource do SqlClient:

Microsoft.Data.SqlClient.EventSource

Para obter mais informações, confira como Habilitar o rastreamento de eventos no SqlClient.

Habilitando a rede gerenciada no Windows

Uma nova opção de AppContext, "Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows" , permite o uso de uma implementação de SNI gerenciado no Windows para fins de teste e depuração. Essa opção alterna o comportamento do driver para usar um SNI gerenciado em projetos .NET Core 2.1+ e .NET Standard 2.0+ no Windows, eliminando todas as dependências de bibliotecas nativas para a biblioteca Microsoft.Data.SqlClient.

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true);

Confira Opções de AppContext no SqlClient para obter uma lista completa de opções disponíveis no driver.

Habilitar o comportamento de truncamento de decimal

O driver arredonda a escala de dados decimais, por padrão, como é feito pelo SQL Server. Para compatibilidade com versões anteriores, você pode definir a opção AppContext "Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal" como true.

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal", true);

Novos sinônimos de propriedade de cadeia de conexão

Novos sinônimos foram adicionados para as propriedades de cadeia de conexão existentes a seguir para evitar a confusão de espaçamento em relação a propriedades com mais de uma palavra. Os nomes de propriedade antigos continuam a ser suportados para compatibilidade com versões anteriores. Mas as novas propriedades da cadeia de conexão agora são incluídas ao buscar a cadeia de conexão de SqlConnectionStringBuilder.

Propriedade de cadeia de conexão existente Novo sinônimo
ApplicationIntent Tentativa de aplicativo
ConnectRetryCount Contagem de repetições de conexão
ConnectRetryInterval Intervalo de repetição de conexão
PoolBlockingPeriod Período de bloqueio do pool
MultipleActiveResultSets Conjuntos de resultados ativos múltiplos
MultiSubnetFailover Failover de várias sub-redes
TransparentNetworkIPResolution Resolução IP de Rede Transparente
TrustServerCertificate Confiar em Certificado do Servidor

Propriedade SqlBulkCopy RowsCopied

A Propriedade RowsCopied fornece acesso somente leitura ao número de linhas que foram processadas na operação de cópia em massa em andamento. Esse valor pode não ser necessariamente igual ao número final de linhas adicionadas à tabela de destino.

Substituições abertas de conexão

O comportamento padrão de SqlConnection.Open() pode ser substituído para desabilitar o atraso de dez segundos e as tentativas de conexão automática disparadas por erros transitórios.

using SqlConnection sqlConnection = new SqlConnection("Data Source=(local);Integrated Security=true;Initial Catalog=AdventureWorks;");
sqlConnection.Open(SqlConnectionOverrides.OpenWithoutRetry);

Observação

Observe que essa substituição só pode ser aplicada a SqlConnection.Open() e não a SqlConnection.OpenAsync().

Suporte de nome de usuário para o modo interativo do Active Directory

Um nome de usuário pode ser especificado na cadeia de conexão ao usar o modo de autenticação interativa do Microsoft Entra ID para .NET Framework e .NET Core

Defina um nome de usuário usando a propriedade de cadeia de conexão ID de Usuário ou UID:

"Server=<server name>; Database=<db name>; Authentication=Active Directory Interactive; User Id=<username>;Encrypt=True;"

Dicas de ordem para SqlBulkCopy

As dicas de ordem podem ser fornecidas para aprimorar o desempenho de operações de cópia em massa em tabelas com índices clusterizados. Para obter mais informações, confira a seção operações de cópia em massa.

Alterações de dependência de SNI

A Microsoft.Data.SqlClient (.NET Core e .NET Standard) no Windows agora é dependente da Microsoft.Data.SqlClient.SNI.runtime, substituindo a dependência anterior de runtime.native.System.Data.SqlClient.SNI. A nova dependência adiciona suporte para a plataforma do ARM junto com as plataformas já compatíveis ARM64, x64 e x86 no Windows.

Suporte à 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 sobre a versão do Microsoft.Data.SqlClient 1.1.0

As notas sobre a versão completas, incluindo dependências, estão disponíveis no Repositório do GitHub: Notas sobre a versão 1.1.

Novos recursos da versão 1.1

Always Encrypted com enclaves seguros

O Always Encrypted está disponível no Microsoft SQL Server 2016 e em versões posteriores. Os enclaves seguros estão disponíveis no Microsoft SQL Server 2019 e em versões posteriores. Para usar o recurso de enclave, as cadeias de conexão devem incluir o protocolo de atestado e a URL de atestado necessários. Por exemplo:

"Attestation Protocol=HGS;Enclave Attestation Url=<attestation_url_for_HGS>"

Para obter mais informações, consulte:

Suporte à 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 sobre a versão do Microsoft.Data.SqlClient 1.0

A versão inicial do namespace Microsoft.Data.SqlClient oferece uma funcionalidade adicional em relação ao namespace System.Data.SqlClient existente.

As notas sobre a versão completas, incluindo dependências, estão disponíveis no Repositório do GitHub: Notas sobre a versão 1.0.

Novos recursos da versão 1.0

Novos recursos no .NET Framework 4.7.2 System.Data.SqlClient

  • Classificação de dados – disponível no Banco de Dados SQL do Azure e no Microsoft SQL Server 2019.

  • Suporte a UTF-8 – disponível no Microsoft SQL Server 2019.

Novos recursos no .NET Core 2.2 System.Data.SqlClient

  • Classificação de dados – disponível no Banco de Dados SQL do Azure e no Microsoft SQL Server 2019.

  • Suporte a UTF-8 – disponível no Microsoft SQL Server 2019.

  • Autenticação – modo de autenticação de senha do Active Directory.

Classificação de dados

A classificação de dados traz um novo conjunto de APIs expondo informações de classificação e a confidencialidade de dados somente leitura sobre objetos recuperados via SqlDataReader quando a fonte subjacente dá suporte ao recurso e contém metadados sobre classificação e confidencialidade de dados. Confira o aplicativo de exemplo em Descoberta de dados e classificação no 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
    }
}

Suporte para UTF-8

O suporte a UTF-8 não requer nenhuma alteração de código do aplicativo. Essas alterações do SqlClient simplesmente otimizam a comunicação entre o cliente e o servidor quando o servidor é compatível com UTF-8 e a ordenação de coluna subjacente é UTF-8. Confira a seção UTF-8 em Novidades no SQL Server 2019.

O Always Encrypted com enclaves seguros

Em geral, a documentação existente que usa System.Data.SqlClient no .NET Framework e provedores internos de repositório de chaves mestras de coluna agora devem funcionar também com o .NET Core.

Desenvolver usando o Always Encrypted com o Provedor de Dados .NET Framework

Always Encrypted: Proteger dados confidenciais e armazenar chaves de criptografia no repositório de certificados do Windows

Autenticação

Modos de autenticação diferentes podem ser especificados usando a opção de cadeia de conexão Authentication. Para obter mais informações, confira a documentação do SqlAuthenticationMethod.

Observação

Provedores de repositório de chaves personalizados, como o provedor do Azure Key Vault, precisarão ser atualizados para dar suporte a Microsoft.Data.SqlClient. Da mesma forma, os provedores de enclave também precisarão ser atualizados para dar suporte ao Microsoft.Data.SqlClient. O Always Encrypted só é compatível com destinos do .NET Framework e do .NET Core. Ele não é compatível com o .NET Standard, já que o .NET Standard não tem determinadas dependências de criptografia.

Suporte à 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)