Introduzione allo spazio dei nomi Microsoft.Data.SqlClient

Scarica ADO.NET

Lo spazio dei nomi Microsoft.Data.SqlClient è essenzialmente una nuova versione dello spazio dei nomi System.Data.SqlClient. Microsoft.Data.SqlClient mantiene in genere la stessa API e la compatibilità con le versioni precedenti di System.Data.SqlClient. Eseguire la migrazione da System.Data.SqlClient a Microsoft.Data.SqlClient, per la maggior parte delle applicazioni è semplice. Aggiungere una dipendenza NuGet da Microsoft.Data.SqlClient e aggiornare i riferimenti e le istruzioni using per Microsoft.Data.SqlClient.

Esistono alcune differenze nelle API meno usate rispetto a System.Data.SqlClient che possono influire su alcune applicazioni. Per queste differenze, vedere questa utile scheda di riferimento rapido sul trasferimento.

Informazioni di riferimento sulle API

I dettagli dell'API Microsoft.Data.SqlClient sono disponibili nel Browser dell'API .NET.

Note sulla versione per Microsoft.Data.SqlClient 5.2

Nuove funzionalità nella versione 5.2

Aggiunta di una nuova proprietà RowsCopied64 a SqlBulkCopy

SqlBulkCopy ha una nuova proprietà RowsCopied64 che supporta long i tipi valore.

Si noti che il comportamento esistente SqlBulkCopy.RowsCopied è invariato. Quando il valore supera int.MaxValue, RowsCopied può restituire un numero negativo.

Sintassi di esempio:

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

Aggiunta di una nuova proprietà AccessTokenCallBack a Sql Connessione ion

Sql Connessione ion supporta TokenCredential l'autenticazione introducendo una nuova AccessTokenCallBack proprietà come Func<SqlAuthenticationParameters, CancellationToken,Task<SqlAuthenticationToken>> delegato per restituire un token di accesso con autenticazione federata.

Sintassi di esempio:

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

SqlBatch API

Sintassi di esempio:

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

5.2 Supporto della piattaforma di destinazione

  • .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)

Le note sulla versione completa, incluse le dipendenze, sono disponibili nel repository GitHub: note sulla versione 5.2.

Modifiche importanti nella versione 5.1

  • Supporto eliminato per .NET Core 3.1. #1704#1823

Nuove caratteristiche della versione 5.1

  • Aggiunta del supporto per DateOnly e TimeOnly per valore SqlParameter e GetFieldValue. #1813
  • Aggiunta del supporto per TLS 1.3 per .NET Core e SNI nativo. #1821
  • Aggiunta dell'impostazione ServerCertificate per Encrypt=Mandatory o Encrypt=Strict. #1822Altre informazioni
  • Aggiunta del supporto di Windows ARM64 quando è destinata a .NET Framework. #1828

Certificato server

Il valore predefinito dell'impostazione di connessione ServerCertificate è una stringa vuota. Quando Encrypt è impostato su Mandatory o Strict, ServerCertificate, può essere usato per specificare un percorso sul file system di un file di certificato da confrontare con il certificato TLS/SSL del server. Il certificato specificato deve essere una corrispondenza esatta, per essere valido. I formati di certificato accettati sono PEM, DER, e CER. Ecco un esempio d'uso:

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

Supporto della piattaforma di destinazione 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)

Le note complete sulla versione, incluse le dipendenze, sono disponibili nel repository GitHub: Note sulla versione 5.1.

Note sulla versione per Microsoft.Data.SqlClient 5.0

Modifiche importanti nella versione 5.0

  • Rimozione del supporto per .NET Framework 4.6.1 #1574
  • Aggiunta di una dipendenza al pacchetto Microsoft.SqlServer.Server. Questa nuova dipendenza può causare conflitti degli spazi dei nomi se l'applicazione fa riferimento a tale spazio dei nomi e contiene comunque riferimenti al pacchetto (diretto o indiretto) a System.Data.SqlClient da .NET Core.
  • Sono state eliminate classi dallo spazio dei nomi Microsoft.Data.SqlClient.Server e sono state sostituite con i tipi supportati dal pacchetto Microsoft.SqlServer.Server. #1585. Le classi e le enumerazioni interessate sono:
    • 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
    • (enumerazione) Microsoft.Data.SqlClient.Server.DataAccessKind -> Microsoft.SqlServer.Server.DataAccessKind
    • (enumerazione) Microsoft.Data.SqlClient.Server.DataAccessKind -> Microsoft.SqlServer.Server.DataAccessKind
    • (enumerazione) Microsoft.Data.SqlClient.Server.SystemDataAccessKind -> Microsoft.SqlServer.Server.SystemDataAccessKind

Nuove funzionalità della versione 5.0

Sicurezza avanzata di TDS 8

Per usare TDS 8, specificare Encrypt=Strict nella stringa di connessione. La modalità strict disabilita TrustServerCertificate (sempre considerata False in modalità strict). HostNameInCertificate è stato aggiunto per semplificare alcuni scenari in modalità strict. TDS 8 avvia e continua tutte le comunicazioni del server all'interno di una connessione TLS protetta e crittografata.

Sono stati aggiunti nuovi valori di Encrypt per chiarire il comportamento di crittografia della connessione. Encrypt=Mandatory equivale a Encrypt=True ed esegue la crittografia delle connessioni durante la negoziazione della connessione TDS. Encrypt=Optional equivale a Encrypt=False ed esegue la crittografia per la connessione solo se il server indica al client che è necessaria la crittografia durante la negoziazione della connessione TDS.

Per altre informazioni sulla crittografia delle connessioni al server, vedere Crittografia e convalida di certificati.

HostNameInCertificate può essere specificato nella stringa di connessione quando si usano gli alias per connettersi con la crittografia a un server che abbia un certificato server con un nome diverso o un nome alternativo del soggetto rispetto al nome usato dal client per identificare il server, ad esempio alias DNS. Esempio di utilizzo: HostNameInCertificate=MyDnsAliasName

SPN server

Quando ci si connette in un ambiente con topografia di dominio/foresta univoca, è possibile che siano previsti requisiti specifici per gli SPN del server. Le impostazioni della stringa di connessione ServerSPN/Server SPN e FailoverServerSPN/Failover Server SPN possono essere usate per eseguire l'override degli SPN del server generati automaticamente usati durante l'autenticazione integrata in un ambiente del dominio

Supporto per gli alias di SQL

Gli utenti possono configurare gli alias usando il Gestione configurazione SQL Server. Questi alias vengono archiviati nel Registro di sistema di Windows e sono già supportati quando la destinazione è .NET Framework. Questa versione offre il supporto per gli alias quando la destinazione è .NET o .NET Core in Windows.

Supporto dell'enumeratore per l'origine dati SQL

Fornisce un meccanismo per enumerare tutte le istanze disponibili di SQL Server all'interno della rete locale.

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

Eliminare gli avvisi TLS non sicuri

Nella console viene generato un avviso di sicurezza se viene usata una versione di TLS precedente alla versione 1.2 per negoziare con il server. Questo avviso potrebbe essere eliminato nella connessione SQL se Encrypt = false abilitando l'opzione AppContext seguente all'avvio dell'applicazione:

Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning

Supporto della piattaforma di destinazione 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)

Le note complete sulla versione, incluse le dipendenze, sono disponibili nel repository GitHub: Note sulla versione 5.0.

Note sulla versione per Microsoft.Data.SqlClient 4.1

Le note complete sulla versione, incluse le dipendenze, sono disponibili nel repository GitHub: Note sulla versione 4.1.

Nuove funzionalità della versione 4.1

Introdurre il protocollo di attestazione None

Nella stringa di connessione sarà consentito un nuovo protocollo di attestazione chiamato None. Questo protocollo consente agli utenti di rinunciare all'attestazione dell'enclave per gli enclavi VBS. Quando questo protocollo è impostato, la proprietà URL di attestazione dell'enclave è facoltativa.

Esempio di stringa di connessione:

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

Supporto della piattaforma di destinazione 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)

Note sulla versione per Microsoft.Data.SqlClient 4.0

Le note complete sulla versione, incluse le dipendenze, sono disponibili nel repository GitHub: Note sulla versione 4.0.

Modifiche importanti nella versione 4.0

  • Modifica della proprietà della stringa di connessione Encrypt in modo che sia true per impostazione predefinita. #1210Altre informazioni
  • Il driver genera ora SqlException che sostituisce AggregateException per le modalità di autenticazione di Active Directory. #1213
  • Proprietà di connessione Asynchronous Processing obsoleta eliminata da .NET Framework. #1148
  • Rimozione dell'opzione di sicurezza Configurable Retry Logic. #1254Altre informazioni
  • Supporto eliminato per .NET Core 2.1 #1272
  • [.NET Framework] L'eccezione non è generata se nella stringa di connessione viene specificato un ID utente quando si usa l'autenticazione Active Directory Integrated#1359

Nuove funzionalità della versione 4.0

Il valore predefinito Encrypt è impostato su true

Il valore predefinito dell'impostazione di connessione Encrypt è stato modificato da false a true. Con il maggiore uso dei database cloud e la necessità di garantire che tali connessioni siano sicure, è ora necessario applicare questa modifica importante relativa alla compatibilità con le versioni precedenti.

Verificare che le connessioni abbiano esito negativo quando è necessaria la crittografia

Negli scenari in cui le librerie della crittografia client sono state disabilitate o non sono disponibili, è stato possibile stabilire connessioni non crittografate quando Encrypt era impostato su true o il server richiedeva la crittografia.

Opzione AppContext per l'uso dei protocolli predefiniti del sistema

TLS 1.3 non è supportato dal driver; pertanto, è stato rimosso dall'elenco di protocolli supportati per impostazione predefinita. Gli utenti possono tornare all'uso forzato dei protocolli client del sistema operativo abilitando l'opzione AppContext di seguito:

Switch.Microsoft.Data.SqlClient.UseSystemDefaultSecureProtocols

Abilitare l'associazione di parametri ottimizzata

Microsoft.Data.SqlClient introduce una nuova API SqlCommand, EnableOptimizedParameterBinding per migliorare le prestazioni delle query con un numero elevato di parametri. Questa proprietà è disabilitata per impostazione predefinita. Se impostati su true, i nomi dei parametri non verranno inviati all’istanza di SQL Server quando viene eseguito il comando.

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

Rimuovere l'opzione di sicurezza della logica di ripetizione dei tentativi configurabile

Il cambio di contesto dell’app AppContext "Switch.Microsoft.Data.SqlClient.EnableRetryLogic" non è più necessaria per usare la funzionalità di logica di ripetizione dei tentativi configurabile. La funzionalità è ora supportata nell'ambiente di produzione. Il comportamento predefinito di questa funzione continua a essere un criterio di non ripetizione, che le applicazioni client devono sovrascrivere per abilitare le ripetizioni.

Supporto dell'istanza condivisa SqlLocalDb

Le istanze condivise SqlLocalDb sono ora supportate quando si usa SNI gestito.

  • Scenari possibili:
    • (localdb)\. (si connette all'istanza predefinita di SqlLocalDb)
    • (localdb)\<named instance>
    • (localdb)\.\<shared instance name> (*supporto appena aggiunto)

Supporto di GetFieldValueAsync<T> e GetFieldValue<T> per i tipi XmlReader, TextReader e Stream

I tipi XmlReader, TextReader e Stream sono ora supportati quando si usano GetFieldValueAsync<T> e GetFieldValue<T>.

Sintassi di esempio:

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

Supporto della piattaforma di destinazione 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)

Note sulla versione per Microsoft.Data.SqlClient 3.0

Le note complete sulla versione, incluse le dipendenze, sono disponibili nel repository GitHub: Note sulla versione 3.0.

Modifiche importanti nella versione 3.0

  • La versione minima supportata di .NET Framework è stata aumentata alla versione 4.6.1. .NET Framework v4.6.0 non è più supportato. #899
  • La proprietà di connessione User Id richiede ora Client Id anziché Object Id per l'identità gestita assegnata dall'utente#1010Altre informazioni
  • SqlDataReader restituisce ora un valore DBNull anziché byte[] vuoto. Il comportamento legacy può essere abilitato impostando l'opzione AppContextSwitch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior#998Altre informazioni

Nuove funzionalità della versione 3.0

Logica di ripetizione dei tentativi configurabile

Questa nuova funzionalità introduce il supporto configurabile per le applicazioni client per ripetere i tentativi in caso di errori "temporanei" o "ripetibili". La configurazione può essere eseguita tramite file di configurazione del codice o dell'app e le operazioni di ripetizione dei tentativi possono essere applicate all'apertura di una connessione o all'esecuzione di un comando. Questa funzionalità è disabilitata per impostazione predefinita ed è attualmente in anteprima. Per abilitare questo supporto, le applicazioni client devono attivare l'opzione di sicurezza seguente:

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

Dopo aver abilitato l'opzione AppContext .NET, è possibile definire un criterio di logica di ripetizione dei tentativi per SqlConnection e SqlCommand in modo indipendente oppure simultaneo usando diverse opzioni di personalizzazione.

Sono state introdotte nuove API pubbliche in SqlConnection e SqlCommand per la registrazione di un'implementazione di SqlRetryLogicBaseProvider personalizzata:

public SqlConnection
{
    public SqlRetryLogicBaseProvider RetryLogicProvider;
}

public SqlCommand
{
    public SqlRetryLogicBaseProvider RetryLogicProvider;
}

Gli esempi di utilizzo delle API sono disponibili qui:

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

Sono state introdotte anche nuove sezioni di configurazione per eseguire la stessa registrazione dai file di configurazione, senza dover modificare il codice esistente:

<section name="SqlConfigurableRetryLogicConnection"
            type="Microsoft.Data.SqlClient.SqlConfigurableRetryConnectionSection, Microsoft.Data.SqlClient"/>

<section name="SqlConfigurableRetryLogicCommand"
            type="Microsoft.Data.SqlClient.SqlConfigurableRetryCommandSection, Microsoft.Data.SqlClient"/>

Ecco un semplice esempio di utilizzo delle nuove sezioni di configurazione nei file di configurazione:

<?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>

In alternativa, le applicazioni possono implementare il proprio provider della classe di base SqlRetryLogicBaseProvider e registrarlo con SqlConnection/SqlCommand.

Contatori di eventi

I contatori seguenti sono ora disponibili per le applicazioni destinate a .NET Core 3.1+ e a .NET Standard 2.1+:

Nome Nome visualizzato Descrizione
active-hard-connections Connessioni attive effettive attualmente stabilite con i server Il numero di connessioni attualmente aperte verso i server di database.
hard-connects Frequenza di connessione effettiva verso i server Il numero di connessioni al secondo aperte verso i server di database.
hard-disconnects Frequenza effettiva di disconnessione dai server Il numero di disconnessioni al secondo eseguite dai server di database.
active-soft-connects Connessioni attive recuperate dal pool di connessioni Numero di connessioni già aperte utilizzate dal pool di connessioni.
soft-connects Frequenza delle connessioni recuperate dal pool di connessioni Il numero di connessioni al secondo utilizzate dal pool di connessioni.
soft-disconnects Frequenza delle connessioni restituite al pool di connessioni Il numero di connessioni al secondo restituite al pool di connessioni.
number-of-non-pooled-connections Numero di connessioni che non usano il pool di connessioni Numero di connessioni attive che non sono nel pool.
number-of-pooled-connections Numero di connessioni gestite dal pool di connessioni Il numero di connessioni attive gestite dall'infrastruttura del pool di connessioni.
number-of-active-connection-pool-groups Numero di stringhe di connessione univoche attive Il numero di gruppi univoci di pool di connessioni attivi. Questo contatore si basa sul numero di stringhe di connessione univoche trovate nell'AppDomain.
number-of-inactive-connection-pool-groups Numero di stringhe di connessione univoche in attesa di eliminazione Il numero di gruppi univoci di pool di connessioni attivi contrassegnati per l'eliminazione. Questo contatore si basa sul numero di stringhe di connessione univoche trovate nell'AppDomain.
number-of-active-connection-pools Numero di pool di connessioni attivi Numero complessivo di pool di connessioni.
number-of-inactive-connection-pools Numero di pool di connessioni inattivi Il numero di pool di connessioni inattivi in cui non si è verificata alcuna attività recente e in attesa di essere eliminati.
number-of-active-connections Numero di connessioni attive Il numero di connessioni attive al momento in uso.
number-of-free-connections Numero di connessioni pronte nel pool di connessioni Numero di connessioni aperte disponibili per l'uso nei pool di connessioni.
number-of-stasis-connections Numero di connessioni attualmente in attesa di essere preparate Numero di connessioni attualmente in attesa del completamento di un'azione e che non sono disponibili per l'uso da parte dell'applicazione.
number-of-reclaimed-connections Numero di connessioni recuperate da GC Il numero di connessioni recuperate tramite Garbage Collection laddove l'applicazione non ha chiamato Close o Dispose. Nota La chiusura o l'eliminazione non esplicita delle connessioni danneggia le prestazioni.

Questi contatori possono essere usati con gli strumenti globali dell'interfaccia della riga di comando di .NET Core dotnet-counters e dotnet-trace in Windows o Linux e PerfView in Windows, usando Microsoft.Data.SqlClient.EventSource come nome del provider. Per altre informazioni, vedere Recuperare i valori dei contatori eventi.

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

Introduzione alle dipendenze di Identità di Azure

Microsoft.Data.SqlClient dipende ora dalla libreria Azure.Identity per l'acquisizione dei token per le modalità di autenticazione "Identità gestita/MSI di Active Directory" e "Entità servizio di Active Directory". Questa modifica cambia l'area di superficie pubblica nel modo seguente:

  • Modifica importante
    La proprietà di connessione "ID utente" richiede ora "ID client" anziché "ID oggetto" per "Identità gestita assegnata dall'utente".
  • API pubblica
    Nuova proprietà pubblica di sola lettura: SqlAuthenticationParameters.ConnectionTimeout
  • Dipendenza
    Azure.Identity v1.3.0

Miglioramenti della traccia degli eventi in SNI.dll

Le versioni Microsoft.Data.SqlClient.SNI (dipendenza di .NET Framework) e Microsoft.Data.SqlClient.SNI.runtime (dipendenza di .NET Core/Standard) sono state aggiornate a v3.0.0-preview1.21104.2. La traccia degli eventi in SNI.dll non è più abilitata tramite un'applicazione client. La sottoscrizione di una sessione al provider Microsoft.Data.SqlClient.EventSource tramite strumenti come xperf o perfview è sufficiente. Per altre informazioni, vedere Supporto per la traccia di eventi in SNI nativo.

Abilitazione del comportamento null della versione di riga

SqlDataReader restituisce un valore DBNull anziché byte[] vuoto. Per abilitare il comportamento legacy, è necessario abilitare l'opzione AppContext seguente all'avvio dell'applicazione: "Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior"

Supporto dell'autenticazione predefinita di Microsoft Entra

Nota

Anche se Microsoft Entra ID è il nuovo nome per Azure Active Directory (Azure AD), per evitare l'interruzione degli ambienti esistenti, Azure AD rimane ancora in alcuni elementi codificati, ad esempio campi dell'interfaccia utente, provider di connessioni, codici di errore e cmdlet. In questo articolo i due nomi sono intercambiabili.

Questa richiesta pull introduce un nuovo metodo di autenticazione SQL, Active Directory predefinito. Questa modalità di autenticazione estende le possibilità di autenticazione utente con Microsoft Entra ID, estendendo le soluzioni di accesso all'ambiente client, a Visual Studio Code, a Visual Studio, all'interfaccia della riga di comando di Azure e così via.

Con questa modalità di autenticazione, il driver acquisisce un token passando "DefaultAzureCredential" dalla libreria di Identità di Azure per acquisire un token di accesso. La modalità tenta di usare questi tipi di credenziali per acquisire un token di accesso nell'ordine seguente:

  • EnvironmentCredential
    • Consente l'autenticazione con Microsoft Entra tramite client e segreto o nome utente e password, i dettagli sono configurati nelle variabili di ambiente seguenti: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_CLIENT_CERTIFICATE_PATH, AZURE_USERNAME, AZURE_PASSWORD (altri dettagli)
  • ManagedIdentityCredential
    • Tenta l'autenticazione con Microsoft Entra usando un'identità gestita assegnata all'ambiente di distribuzione. L"ID Client" di una "identità gestita assegnata dall'utente" viene letto dalla proprietà di connessione "User Id".
  • SharedTokenCacheCredential
    • Esegue l'autenticazione usando i token nella cache locale condivisa tra le applicazioni Microsoft.
  • VisualStudioCredential
    • Abilita l'autenticazione con Microsoft Entra ID usando i dati di Visual Studio
  • VisualStudioCodeCredential
    • Abilita l'autenticazione con Microsoft Entra ID usando i dati di Visual Studio Code.
  • AzureCliCredential
    • Abilita l'autenticazione con Microsoft Entra ID usando l'interfaccia della riga di comando di Azure per ottenere un token di accesso.

InteractiveBrowserCredential è disabilitato nell'implementazione del driver "Active Directory predefinito" e "Active Directory interattivo" è l'unica opzione disponibile per acquisire un token tramite autenticazione MFA/interattiva.*

Al momento non sono disponibili altre opzioni di personalizzazione.

Miglioramenti della registrazione per il provider dell'archivio chiavi master personalizzato

Microsoft.Data.SqlClient consente ora di controllare maggiormente la posizione in cui i provider dell'archivio chiavi master sono accessibili in un'applicazione, per supportare meglio le applicazioni multi-tenant e il loro uso della crittografia/decrittografia delle colonne. Vengono introdotte le API seguenti per consentire la registrazione dei provider dell'archivio chiavi master personalizzati nelle istanze di SqlConnection e SqlCommand:

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

L'API statica in SqlConnection, SqlConnection.RegisterColumnEncryptionKeyStoreProviders, usata per registrare i provider dell'archivio chiavi master personalizzati a livello globale, è ancora supportata. La cache delle chiavi di crittografia della colonna gestita a livello globale si applica solo ai provider registrati a livello globale.

Precedenza della registrazione per il provider dell'archivio chiavi master della colonna

I provider di archivi chiavi master di colonna predefiniti disponibili per l'archivio certificati di Windows, l'archivio CNG e CSP sono preregistrati. Nelle istanze di connessione o di comando non deve essere registrato alcun provider se è necessario uno dei provider dell'archivio chiavi master della colonna predefinito.

I provider di archivi chiavi master personalizzati possono essere registrati con il driver a tre livelli diversi. Il livello globale è così come è attualmente. Le nuove registrazioni per connessione e per comando sono inizialmente vuote e possono essere impostate più volte.

Le precedenze delle tre registrazioni sono le seguenti:

  • Viene verificata la registrazione per comando, se non è vuota.
  • Se la registrazione per comando è vuota, verrà verificata la registrazione per connessione, se non è vuota.
  • Se la registrazione per connessione è vuota, viene controllata la registrazione globale.

Dopo aver individuato un provider dell'archivio chiavi a livello di registrazione, il driver NON esegue il fallback alle altre registrazioni per cercare un provider. Se i provider sono registrati, ma il provider appropriato non viene trovato a un determinato livello, viene generata un'eccezione che contiene solo i provider registrati nella registrazione controllata.

Precedenza della cache della chiave di crittografia della colonna

Il driver non memorizza nella cache le chiavi di crittografia delle colonne (CEK) per i fornitori di archivi di chiavi personalizzati registrati utilizzando le nuove API a livello di istanza. Per ottenere buone prestazioni, i provider dell'archivio chiavi devono implementare la propria cache. Il driver disabilita la cache locale delle chiavi di crittografia delle colonne implementate dai provider di archivi di chiavi personalizzati se l'istanza del provider di archivi di chiavi è registrata nel driver a livello globale.

È stata introdotta anche una nuova API nella classe di base SqlColumnEncryptionKeyStoreProvider per impostare la durata della 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);
}

Preferenza degli indirizzi IP

Viene introdotta una nuova proprietà di connessione IPAddressPreference per specificare la preferenza della famiglia di indirizzi IP per il driver quando si stabiliscono connessioni TCP. Se Transparent Network IP Resolution, in .NET Framework, o Multi Subnet Failover è impostato su true, questa impostazione non ha alcun effetto. Sono tre, i valori accettati per questa proprietà:

  • IPv4First

    • Si tratta del valore predefinito. Il driver usa prima gli indirizzi IPv4 risolti. Se nessuno di essi può essere connesso correttamente, prova a usare gli indirizzi IPv6 risolti.
  • IPv6First

    • Il driver usa prima gli indirizzi IPv6 risolti. Se nessuno di essi può essere connesso correttamente, prova a usare gli indirizzi IPv4 risolti.
  • UsePlatformDefault

    • Il driver prova a usare gli indirizzi IP nell'ordine ricevuto dalla risposta di risoluzione DNS.

Supporto della piattaforma di destinazione 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)

Note sulla versione per Microsoft.Data.SqlClient 2.1

Le note complete sulla versione, incluse le dipendenze, sono disponibili nel repository GitHub: Note sulla versione 2.1.

Nuove funzionalità della versione 2.1

Supporto multipiattaforma per Always Encrypted

Microsoft. Data. SqlClient v 2.1 estende il supporto per Always Encrypted alle piattaforme seguenti:

Supporto per Always Encrypted Supporto per Always Encrypted con enclave sicura Framework di destinazione Versione di Microsoft.Data.SqlClient Sistema operativo
.NET Framework 4.6+ 1.1.0+ Windows
.NET Core 2.1+ 2.1.0+1 Windows, Linux, macOS
No2 .NET Standard 2.0 2.1.0+ Windows, Linux, macOS
.NET Standard 2.1+ 2.1.0+ Windows, Linux, macOS

Nota

1 Prima di Microsoft.Data.SqlClient versione v2.1, Always Encrypted era supportato solo in Windows. 2 Always Encrypted con enclave sicure non è supportato in .NET Standard 2.0.

Autenticazione del flusso di codice del dispositivo Microsoft Entra

Microsoft. Data. SqlClient v 2.1 fornisce il supporto per l'autenticazione "Flusso di codice del dispositivo" con MSAL.NET. Documentazione di riferimento: Flusso di concessione dell'autorizzazione del dispositivo OAuth2.0

Esempio di stringa di connessione:

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

L'API seguente consente la personalizzazione del meccanismo di callback del flusso di codice del dispositivo:

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

Autenticazione dell’identità gestita di Microsoft Entra

Microsoft.Data.SqlClient v2.1 introduce il supporto per l'autenticazione di Microsoft Entra tramite identità gestite.

Sono supportate le parole chiave dei tipi di autenticazione seguenti:

  • Identità gestita di Active Directory
  • Active Directory MSI (per compatibilità incrociata con i driver MS SQL)

Esempi di stringhe di connessione:

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

Miglioramenti all'autenticazione interattiva di Microsoft Entra

Microsoft.Data.SqlClient v2.1 aggiunge le API seguenti per personalizzare l'esperienza di autenticazione interattiva di Microsoft Entra:

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

SqlClientAuthenticationProviders Sezione Configurazione

Microsoft.Data.SqlClient v2.1 introduce una nuova sezione di configurazione, SqlClientAuthenticationProviders (un clone della SqlAuthenticationProviders esistente). La sezione di configurazione esistente, SqlAuthenticationProviders, è ancora supportata per la compatibilità con le versioni precedenti quando viene definito il tipo appropriato.

La nuova sezione consente ai file di configurazione dell'applicazione di contenere sia una sezione SqlAuthenticationProviders per System.Data.SqlClient che una sezione SqlClientAuthenticationProviders per Microsoft.Data.SqlClient.

Autenticazione di Microsoft Entra con un ID client dell'applicazione

Microsoft.Data.SqlClient v2.1 introduce il supporto per il passaggio di un ID client dell'applicazione definito dall'utente a Microsoft Authentication Library. L'ID client dell'applicazione viene usato per l'autenticazione con Microsoft Entra ID.

Sono state introdotte le nuove API seguenti:

  1. Un nuovo costruttore è stato introdotto in ActiveDirectoryAuthenticationProvider:
    [Si applica a tutte le piattaforme .NET (.NET Framework, .NET Core e .NET Standard)]

    public ActiveDirectoryAuthenticationProvider(string applicationClientId)
    

    Utilizzo:

    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. Una nuova proprietà di configurazione è stata introdotta in SqlAuthenticationProviderConfigurationSection e SqlClientAuthenticationProviderConfigurationSection:
    [Si applica 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
    { ... }
    

    Utilizzo:

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

Supporto della classificazione dei dati v2

Microsoft.Data.SqlClient v2.1 introduce il supporto per le informazioni sul "livello di riservatezza" della classificazione dei dati. Sono ora disponibili le nuove API seguenti:

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 del processo server per un SqlConnection attivo

Microsoft.Data.SqlClient v2.1 introduce una nuova proprietà SqlConnection, ServerProcessId, in una connessione attiva.

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

Supporto della registrazione delle tracce in SNI nativo

Microsoft.Data.SqlClient v2.1 estende l'implementazione di SqlClientEventSource esistente per abilitare la traccia eventi in SNI.dll. Gli eventi devono essere acquisiti usando uno strumento come Xperf.

La traccia può essere abilitata inviando un comando a SqlClientEventSource come illustrato:

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

Proprietà della stringa di connessione "timeout comando"

Microsoft.Data.SqlClient v2.1 introduce la proprietà della stringa di connessione "timeout comando" per sovrascrivere il valore predefinito di 30 secondi. Il timeout per i singoli comandi può essere sovrascritto tramite la proprietà CommandTimeout in SqlCommand.

Esempi di stringhe di connessione:

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

Rimozione di simboli da SNI nativi

Con Microsoft.Data.SqlClient v2.1 sono stati rimossi i simboli introdotti nella versione v2.0.0 dal NuGet Microsoft.Data.SqlClient.SNI.runtime a partire dalla versione v 2.1.1. I simboli pubblici vengono ora pubblicati in Microsoft symbols server per strumenti come BinSkim che richiedono l'accesso ai simboli pubblici.

Collegamento di origine dei simboli Microsoft.Data.SqlClient

A partire da Microsoft.Data.SqlClient v 2.1, i simboli Microsoft. Data. SqlClient sono collegati al codice sorgente e pubblicati nel server Microsoft symbols per un'esperienza di debug avanzata senza necessità di scaricare il codice sorgente.

Supporto della piattaforma di destinazione 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)

Note sulla versione per Microsoft.Data.SqlClient 2.0

Le note complete sulla versione, incluse le dipendenze, sono disponibili nel repository GitHub: Note sulla versione 2.0.

Modifiche importanti nella versione 2.0

  • Il modificatore di accesso per l'interfaccia del provider di enclave SqlColumnEncryptionEnclaveProvider è stato modificato da public a internal.
  • Le costanti nella classe SqlClientMetaDataCollectionNames sono state aggiornate in modo da riflettere le modifiche apportate a SQL Server.
  • Il driver esegue ora la convalida del certificato del server quando l'istanza di SQL Server di destinazione applica la crittografia TLS, che è l'impostazione predefinita per le connessioni di Azure.
  • SqlDataReader.GetSchemaTable() restituisce ora una stringa DataTable vuota invece di null.
  • Il driver esegue ora l'arrotondamento delle cifre decimali in modo che corrisponda al comportamento di SQL Server. Per la compatibilità con le versioni precedenti, è possibile abilitare il comportamento di troncamento precedente usando un'opzione di AppContext.
  • Per le applicazioni .NET Framework che usano Microsoft.Data.SqlClient, i file SNI.dll scaricati in precedenza nelle cartelle bin\x64 e bin\x86 sono ora denominati Microsoft.Data.SqlClient.SNI.x64.dll e Microsoft.Data.SqlClient.SNI.x86.dll e verranno scaricati nella directory bin.
  • Nuovi sinonimi delle proprietà della stringa di connessione sostituiscono le proprietà obsolete durante il recupero della stringa di connessione da SqlConnectionStringBuilder per coerenza. Altre informazioni

Nuove funzionalità della versione 2.0

Le nuove funzionalità seguenti sono state introdotte in Microsoft.Data.SqlClient 2.0.

Resilienza agli errori DNS

Il driver ora memorizza nella cache gli indirizzi IP da ogni connessione riuscita a un endpoint SQL Server che supporta la funzionalità. Se si verifica un errore di risoluzione DNS durante un tentativo di connessione, il driver tenterà di stabilire una connessione usando un indirizzo IP memorizzato nella cache per il server, se presente.

Traccia EventSource

Questa versione introduce il supporto per l'acquisizione dei log di traccia eventi per il debug delle applicazioni. Per acquisire questi eventi, le applicazioni client devono restare in ascolto degli eventi dall'implementazione EventSource di SqlClient:

Microsoft.Data.SqlClient.EventSource

Per altre informazioni, vedere Come abilitare la traccia eventi in SqlClient.

Abilitazione di reti gestite in Windows

Una nuova opzione di AppContext, "Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", consente l'uso di un'implementazione di SNI gestita in Windows per scopi di test e debug. Questa opzione attiva o disattiva il comportamento del driver in modo da usare uno SNI gestito in progetti .NET Core 2.1+ e .NET Standard 2.0+ in Windows, eliminando tutte le dipendenze dalle librerie native per la libreria Microsoft. Data.SqlClient.

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

Per un elenco completo delle opzioni disponibili nel driver, vedere Opzioni di AppContext in SqlClient.

Abilitazione del comportamento di troncamento decimale

Il driver arrotonda la scala dei dati decimali, per impostazione predefinita, come fa SQL Server. Per la compatibilità con le versioni precedenti, è possibile impostare l'opzione di AppContext "Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal" su true.

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

Nuovi sinonimi delle proprietà della stringa di connessione

Sono stati aggiunti nuovi sinonimi per le proprietà della stringa di connessione esistenti seguenti per evitare problemi di spaziatura tra le proprietà con più di una parola. I nomi delle proprietà precedenti continuano a essere supportati per la compatibilità con le versioni precedenti. Tuttavia, le nuove proprietà di stringa di connessione vengono ora incluse durante il recupero del stringa di connessione da Sql Connessione ionStringBuilder.

Proprietà della stringa di connessione esistente Nuovo sinonimo
ApplicationIntent Application Intent
ConnectRetryCount Numero di tentativi di connessione
ConnectRetryInterval Intervallo dei tentativi di connessione
PoolBlockingPeriod Periodo di blocco del pool
MultipleActiveResultSets Più set di risultati attivi
MultiSubnetFailover Failover di più subnet
TransparentNetworkIPResolution Risoluzione dell'IP di rete trasparente
TrustServerCertificate TrustServerCertificate

Proprietà RowsCopied di SqlBulkCopy

La proprietà RowsCopied fornisce accesso in sola lettura al numero di righe elaborate durante l'operazione di copia bulk in corso. Questo valore non deve necessariamente essere uguale al numero finale di righe aggiunte alla tabella di destinazione.

Override dell'apertura della connessione

È possibile eseguire l'override del comportamento predefinito di SqlConnection.Open() per disabilitare il ritardo di dieci secondi e i tentativi di connessione automatici attivati da errori temporanei.

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

Nota

Si noti che questo override può essere applicato solo a SqlConnection.Open() e non a SqlConnection.OpenAsync().

Supporto di nomi utente per la modalità interattiva di Azure Active Directory

È possibile specificare un nome utente nella stringa di connessione quando si usa la modalità di autenticazione interattiva di Microsoft Entra per .NET Framework e .NET Core

Impostare un nome utente usando la proprietà User ID o UID della stringa di connessione:

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

Suggerimenti per l'ordinamento per SqlBulkCopy

È possibile fornire suggerimenti per l'ordinamento per migliorare le prestazioni delle operazioni di copia bulk sulle tabelle con indici cluster. Per altre informazioni, vedere la sezione Operazioni di copia bulk.

Modifiche alle dipendenze di SNI

Microsoft.Data.SqlClient (.NET Core e .NET Standard) in Windows è ora dipendente da Microsoft.Data.SqlClient.SNI.runtime, in sostituzione alla precedente dipendenza da runtime.native.System.Data.SqlClient.SNI. La nuova dipendenza aggiunge il supporto per la piattaforma ARM insieme alle piattaforme già supportate ARM64, x64 e x86 in Windows.

Supporto della piattaforma di destinazione 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)

Note sulla versione per Microsoft.Data.SqlClient 1.1.0

Le note complete sulla versione, incluse le dipendenze, sono disponibili nel repository GitHub: Note sulla versione 1.1.

Nuove funzionalità della versione 1.1

Always Encrypted con enclave sicuri

Always Encrypted è disponibile a partire da Microsoft SQL Server 2016. Gli enclave sicuri sono disponibili a partire da Microsoft SQL Server 2019. Per usare la funzionalità di enclave, le stringhe di connessione devono includere il protocollo di attestazione e l'URL di attestazione necessari. Ad esempio:

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

Per altre informazioni, vedi:

Supporto della piattaforma di destinazione 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)

Note sulla versione per Microsoft.Data.SqlClient 1.0

La versione iniziale dello spazio dei nomi Microsoft.Data.SqlClient offre maggiori funzionalità rispetto allo spazio dei nomi System.Data.SqlClient esistente.

Le note complete sulla versione, incluse le dipendenze, sono disponibili nel repository GitHub: Note sulla versione 1.0.

Nuove funzionalità della versione 1.0

Nuove funzionalità rispetto a .NET Framework 4.7.2 System.Data.SqlClient

  • Classificazione dei dati: disponibile nel database SQL di Azure e in Microsoft SQL Server 2019.

  • Supporto UTF-8: disponibile in Microsoft SQL Server 2019.

Nuove funzionalità rispetto a .NET Core 2.2 System.Data.SqlClient

  • Classificazione dei dati: disponibile nel database SQL di Azure e in Microsoft SQL Server 2019.

  • Supporto UTF-8: disponibile in Microsoft SQL Server 2019.

  • Autenticazione: modalità di autenticazione con password di Active Directory.

Classificazione dei dati

La classificazione dei dati offre un nuovo set di API che espongono informazioni di sola lettura sulla riservatezza e classificazione dei dati relative agli oggetti recuperati tramite SqlDataReader quando l'origine sottostante supporta la funzionalità e contiene metadati di riservatezza e classificazione dei dati. Vedere l'applicazione di esempio in Data Discovery and Classification in 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
    }
}

Supporto UTF-8

Il supporto UTF-8 non richiede modifiche al codice dell'applicazione. Queste modifiche di SqlClient consentono di ottimizzare la comunicazione tra il client e il server quando il server supporta UTF-8 e le regole di confronto delle colonne sottostanti usano UTF-8. Vedere la sezione UTF-8 in Novità di SQL Server 2019.

Always Encrypted con enclave sicuri

In generale, la documentazione esistente che usa System.Data.SqlClient in .NET Framework e i provider dell'archivio chiavi master delle colonne predefiniti può ora essere usata anche con .NET Core.

Sviluppare con Always Encrypted e il provider di dati .NET Framework

Always Encrypted: proteggere i dati sensibili e archiviare le chiavi di crittografia nell'archivio certificati di Windows

Autenticazione

È possibile specificare modalità di autenticazione diverse usando l'opzione della stringa di connessione Authentication. Per altre informazioni, vedere la documentazione di SqlAuthenticationMethod.

Nota

I provider dell'archivio chiavi personalizzati, come il provider Azure Key Vault, dovranno essere aggiornati per supportare Microsoft.Data.SqlClient. In modo analogo, anche i provider di enclave dovranno essere aggiornati per supportare Microsoft.Data.SqlClient. Always Encrypted è supportato solo su destinazioni .NET Framework e .NET Core. Non è supportato su .NET Standard perché in .NET Standard mancano alcune dipendenze di crittografia.

Supporto della piattaforma di destinazione 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)