Поделиться через


Введение в пространство имен Microsoft.Data.SqlClient

Скачать ADO.NET

Пространство имен Microsoft.Data.SqlClient по сути является новой версией пространства имен System.Data.SqlClient. Microsoft.Data.SqlClient обычно поддерживает те же API и обратную совместимость, что и System.Data.SqlClient. Для большинства приложений переход с System.Data.SqlClient на Microsoft.Data.SqlClient не составляет проблем. Добавьте зависимость NuGet в Microsoft.Data.SqlClient, после чего обновите ссылки и инструкции using в Microsoft.Data.SqlClient.

В этой версии пространства имен есть несколько различий в менее используемых API по сравнению с System.Data.SqlClient, которые могут повлиять на некоторые приложения. Для этих различий обратитесь к полезному памятку по переносу.

Справочник по API

Сведения об API Microsoft.Data.SqlClient можно найти в обозревателе API .NET.

Заметки о выпуске Microsoft.Data.SqlClient 5.2

Новые возможности в версии 5.2

Добавлено новое свойство RowsCopied64 в SqlBulkCopy

SqlBulkCopy имеет новое свойство RowsCopied64 , которое поддерживает long типы значений.

Обратите внимание, что существующее SqlBulkCopy.RowsCopied поведение не изменяется. При превышении int.MaxValueRowsCopied значения может возвращать отрицательное число.

Пример использования:

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

Добавлено новое свойство AccessTokenCallBack в SqlConnection

SqlConnection поддерживает TokenCredential проверку подлинности, введя новое AccessTokenCallBack свойство в качестве Func<SqlAuthenticationParameters, CancellationToken,Task<SqlAuthenticationToken>> делегата для возврата маркера доступа к федеративной проверке подлинности.

Пример использования:

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

const string defaultScopeSuffix = "/.default";
string connectionString = GetConnectionString();
DefaultAzureCredential credential = new();
using SqlConnection connection = new(connectionString);

connection.AccessTokenCallback = async (authParams, cancellationToken) =>
{
    string scope = authParams.Resource.EndsWith(defaultScopeSuffix)
        ? authParams.Resource
        : $"{authParams.Resource}{defaultScopeSuffix}";
    AccessToken token = await cred.GetTokenAsync(
        new TokenRequestContext([scope]),
        cancellationToken);

    return new SqlAuthenticationToken(token.Token, token.ExpiresOn);
}

connection.Open();
Console.WriteLine("ServerVersion: {0}", connection.ServerVersion);
Console.WriteLine("State: {0}", connection.State);

SqlBatch API

Пример использования:

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

  • Платформа .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)

Полные заметки о выпуске, включая зависимости, доступны в репозитории GitHub: заметки о выпуске 5.2.

Критические изменения в версии 5.1

  • Удалена поддержка .NET Core 3.1. #1704 #1823

Новые возможности в версии 5.1

  • Добавлена поддержка значений DateOnly и SqlParameter TimeOnly GetFieldValueзначений. #1813
  • Добавлена поддержка TLS 1.3 для .NET Core и SNI Native. #1821
  • Добавлен параметр ServerCertificate для Encrypt=Mandatory или Encrypt=Strict. #1822 Подробнее
  • Добавлена поддержка Windows ARM64 при выборе платформа .NET Framework. #1828

Сертификат сервера

Значение ServerCertificate по умолчанию параметра подключения является пустой строкой. Если Encrypt задано Mandatory значение или StrictServerCertificate может использоваться для указания пути в файловой системе к файлу сертификата для сопоставления с TLS/SSL-сертификатом сервера. Указанный сертификат должен быть точным, чтобы быть допустимым. Допустимые форматы сертификатов: PEMи DERCER. Пример использования этой команды:

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

Поддержка целевой платформы 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)

Полные заметки о выпуске, включая зависимости, доступны в репозитории GitHub: заметки о выпуске 5.1.

Заметки о выпуске для Microsoft.Data.SqlClient 5.0

Критические изменения в версии 5.0

  • Удалена поддержка .NET Framework 4.6.1 № 1574
  • Добавлена зависимость от пакета Microsoft.SqlServer.Server. Эта новая зависимость может вызвать конфликты пространств имен, если ваше приложение ссылается на это пространство имен и по-прежнему имеет ссылки на пакеты (прямые или косвенные) на System.Data.SqlClient из .NET Core.
  • Удалены классы из пространства имен Microsoft.Data.SqlClient.Server и заменены поддерживаемыми типами из пакета Microsoft.SqlServer.Server.№ 1585. Затронутые классы и перечисления:
    • Microsoft.Data.SqlClient.Server.IBinarySerialize -> Microsoft.SqlServer.Server.IBinarySerialize
    • Microsoft.Data.SqlClient.Server.InvalidUdtException -> Microsoft.SqlServer.Server.InvalidUdtException
    • Microsoft.Data.SqlClient.Server.SqlFacetAttribute -> Microsoft.SqlServer.Server.SqlFacetAttribute
    • Microsoft.Data.SqlClient.Server.SqlFunctionAttribute -> Microsoft.SqlServer.Server.SqlFunctionAttribute
    • Microsoft.Data.SqlClient.Server.SqlMethodAttribute -> Microsoft.SqlServer.Server.SqlMethodAttribute
    • Microsoft.Data.SqlClient.Server.SqlUserDefinedAggregateAttribute -> Microsoft.SqlServer.Server.SqlUserDefinedAggregateAttribute
    • Microsoft.Data.SqlClient.Server.SqlUserDefinedTypeAttribute -> Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute
    • (enum) Microsoft.Data.SqlClient.Server.DataAccessKind -> Microsoft.SqlServer.Server.DataAccessKind
    • (enum) Microsoft.Data.SqlClient.Server.Format -> Microsoft.SqlServer.Server.Format
    • (enum) Microsoft.Data.SqlClient.Server.SystemDataAccessKind -> Microsoft.SqlServer.Server.SystemDataAccessKind

Новые возможности в версии 5.0

  • Добавлена поддержка TDS8. Чтобы использовать TDS 8, пользователи должны указать Encrypt=Strict в строке подключения. #1608 Подробнее
  • Добавлена поддержка указания имени субъекта-службы сервера и имени субъекта-службы сервера отработки отказа в подключении. #1607 Подробнее
  • Добавлена поддержка псевдонимов при нацеливании на .NET Core в Windows. #1588 Подробнее
  • Added SqlDataSourceEnumerator. № 1430, Подробнее
  • Добавлен новый переключатель AppContext для подавления небезопасных предупреждений TLS. № 1457, Подробнее

Повышенная безопасность TDS 8

Чтобы использовать TDS 8, укажите Encrypt=Strict в строке подключения. Строгий режим отключает TrustServerCertificate (всегда обрабатывается как False в строгом режиме). HostNameInCertificate добавлен для помощи в некоторых сценариях строгого режима. Запускается TDS 8 и продолжает все серверные подключения внутри безопасного зашифрованного TLS-подключения.

Добавлены новые значения шифрования для уточнения поведения шифрования подключений. Encrypt=Mandatory эквивалентно Encrypt=True и шифрует соединения во время согласования соединения TDS. Encrypt=Optional эквивалентно Encrypt=False и шифрует соединение только в том случае, если сервер сообщает клиенту, что шифрование требуется во время согласования подключения TDS.

Дополнительные сведения о шифровании подключений к серверу см. в разделе "Шифрование и проверка сертификатов".

HostNameInCertificate можно указать в строке подключения при использовании псевдонимов для подключения к серверу с сертификатом сервера с другим именем или именем субъекта, отличающимся от имени, используемого клиентом для идентификации сервера (например, псевдонимы DNS). Пример использования: HostNameInCertificate=MyDnsAliasName

Server SPN

При подключении в среде с уникальной топографией домена/леса у вас могут быть особые требования к именам субъектов-служб сервера. Параметры spN сервера ServerSPN/Server SPN и failoverServerSPN/Failover Server SPN строка подключения можно использовать для переопределения автоматически созданных имен субъектов-служб сервера, используемых во время интегрированной проверки подлинности в среде домена.

Поддержка псевдонимов SQL

Пользователи могут настраивать псевдонимы с помощью диспетчера конфигурации SQL Server. Эти псевдонимы хранятся в реестре Windows и уже поддерживаются при выборе платформы .NET Framework. Этот выпуск обеспечивает поддержку псевдонимов при выборе .NET или .NET Core в Windows.

Поддержка перечислителя источников данных SQL

Предоставляет механизм перечисления всех доступных экземпляров SQL Server в локальной сети.

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

Отключение предупреждений о небезопасном протоколе TLS

На консоль выводится предупреждение системы безопасности, если для согласования с сервером используется версия TLS ниже 1.2. Это предупреждение можно скрыть при подключении SQL, включив следующий переключатель AppContext при обнаружении приложений, если Encrypt = false:

Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning

Поддержка целевой платформы 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)

Полные заметки о выпуске, в том числе зависимости, доступны в репозитории GitHub: Заметки о выпуске 5.0.

Заметки о выпуске для Microsoft.Data.SqlClient 4.1

Полные заметки о выпуске, в том числе зависимости, доступны в репозитории GitHub: заметки о выпуске 4.1.

Новые возможности в версии 4.1

Представлен протокол аттестации None

В строка подключения разрешен новый протокол None аттестации. Этот протокол позволяет пользователям заготовить аттестацию анклава для VBS анклава. Если выбран этот протокол, свойство URL-адреса аттестации анклава становится необязательным.

Пример строки подключения:

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

Поддержка целевой платформы 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)

Заметки о выпуске для Microsoft.Data.SqlClient 4.0

Полные заметки о выпуске, в том числе зависимости, доступны в репозитории GitHub: заметки о выпуске 4.0.

Критические изменения в версии 4.0

  • Изменено свойство строки подключения Encrypt на true по умолчанию. № 1210 Подробнее
  • Теперь драйвер выдает SqlException в качестве замены AggregateException для режимов проверки подлинности Active Directory. № 1213
  • Удалено устаревшее свойство подключения Asynchronous Processingиз платформы .NET Framework. № 1148
  • Удален параметр-переключатель безопасности Configurable Retry Logic. № 1254 Подробнее
  • Прекращена поддержка .NET Core 2.1 № 1272
  • [платформа .NET Framework] Исключение не возникает, если идентификатор пользователя указан в строка подключения при использовании Active Directory Integrated проверки подлинности #1359

Новые возможности в версии 4.0

Значение параметра Encrypt по умолчанию заменено на true

Значение параметра подключения Encrypt по умолчанию изменено с false на true. В связи с растущим использованием облачных баз данных и необходимостью обеспечить безопасность этих подключений, пришло время для этого изменения, нарушающего обратную совместимость.

Подключения должны завершаться сбоем, если требуется шифрование

В сценариях, где клиентские библиотеки шифрования были отключены или недоступны, можно было установить незашифрованные подключения, если для параметра Encrypt было задано значение true или для сервера требовалось шифрование.

Переключение контекста приложения для использования системных протоколов по умолчанию

TLS 1.3 не поддерживается драйвером, поэтому он был удален из списка поддерживаемых протоколов по умолчанию. Пользователи могут вернуться к принудительному использованию клиентских протоколов операционной системы, включив следующий переключатель контекста приложения:

Switch.Microsoft.Data.SqlClient.UseSystemDefaultSecureProtocols

Включение оптимизированной привязки параметра

Microsoft.Data.SqlClient представляет новый API SqlCommand EnableOptimizedParameterBinding для повышения производительности запросов с большим количеством параметров. По умолчанию это свойство отключено. Если задано значение true, имена параметров не отправляются в экземпляр SQL Server при выполнении команды.

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

Удаление настраиваемого параметра-переключателя безопасности логики повторных попыток

Переключатель контекста приложения Switch.Microsoft.Data.SqlClient.EnableRetryLogic больше не требуется для использования настраиваемой функции логики повторных попыток. Теперь эта функция поддерживается в рабочей среде. Поведение функции по умолчанию по-прежнему является политикой без повторных попыток, которую клиентские приложения должны переопределить для включения повторных попыток.

Поддержка общего экземпляра SqlLocalDb

Теперь при использовании управляемого SNI поддерживаются общие экземпляры SqlLocalDb.

  • Возможные сценарии:
    • (localdb)\. (подключается к экземпляру SqlLocalDb по умолчанию)
    • (localdb)\<named instance>
    • (localdb)\.\<shared instance name> (*недавно включенная поддержка)

Поддержка GetFieldValueAsync<T> и GetFieldValue<T> для типов XmlReader, TextReader, Stream

Типы XmlReader, TextReader, Stream теперь поддерживаются при использовании GetFieldValueAsync<T> и GetFieldValue<T>.

Пример использования:

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

Поддержка целевой платформы 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)

Заметки о выпуске для Microsoft.Data.SqlClient 3.0

Полные заметки о выпуске, в том числе зависимости, доступны в репозитории GitHub: заметки о выпуске 3.0.

Критические изменения в версии 3.0

  • Минимальная поддерживаемая версия платформы .NET Framework повысилась до версии 4.6.1. Версия .NET Framework 4.6.0 больше не поддерживается. #899
  • Теперь для свойства подключения User Id требуется Client Id вместо Object Id для управляемого удостоверения, назначаемого пользователем #1010 Дополнительные сведения
  • SqlDataReader теперь возвращает значение DBNull вместо пустого массива byte[]. Прежнее поведение можно включить, задав параметр AppContext Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior #998 Дополнительные сведения

Новые возможности в версии 3.0

Настраиваемая логика повторных попыток

Эта новая функция предоставляет настраиваемую возможность повторного выполнения в случае временных или устранимых ошибок в клиентских приложениях. Настраивается она в коде или в файлах конфигурации приложения, а повторно выполнять можно операции открытия соединения или выполнения команды. По умолчанию эта функция отключена и в настоящее время доступна в качестве предварительной версии. Чтобы включить ее поддержку, в клиентском приложении необходимо использовать следующий параметр безопасности:

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

После включения параметра .NET AppContext политику логики повторных попыток можно определить отдельно для SqlConnection и SqlCommand или вместе с помощью различных параметров настройки.

В SqlConnection и SqlCommand появились новые общедоступные интерфейсы API для регистрации пользовательской реализации SqlRetryLogicBaseProvider:

public SqlConnection
{
    public SqlRetryLogicBaseProvider RetryLogicProvider;
}

public SqlCommand
{
    public SqlRetryLogicBaseProvider RetryLogicProvider;
}

Примеры использования API см. здесь:

using Microsoft.Data.SqlClient;

/// Detecting retriable exceptions is a vital part of the retry pattern.
/// Before applying retry logic it is important to investigate exceptions and choose a retry provider that best fits your scenario.
/// First, log your exceptions and find transient faults.
/// The purpose of this sample is to illustrate how to use this feature and the condition might not be realistic.
class RetryLogicSample
{
    private const string DefaultDB = "Northwind";
    private const string CnnStringFormat = "Server=localhost; Initial Catalog={0}; Integrated Security=true; pooling=false;";
    private const string DropDatabaseFormat = "DROP DATABASE {0}";

    // For general use
    private static SqlConnection s_generalConnection = new SqlConnection(string.Format(CnnStringFormat, DefaultDB));

    static void Main(string[] args)
    {
        // 1. Define the retry logic parameters
        var options = new SqlRetryLogicOption()
        {
            NumberOfTries = 5,
            MaxTimeInterval = TimeSpan.FromSeconds(20),
            DeltaTime = TimeSpan.FromSeconds(1)
        };

        // 2. Create a retry provider
        var provider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(options);

        // define the retrying event to report the execution attempts
        provider.Retrying += (object s, SqlRetryingEventArgs e) =>
            {
                int attempts = e.RetryCount + 1;
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine($"attempt {attempts} - current delay time:{e.Delay} \n");
                Console.ForegroundColor = ConsoleColor.DarkGray;
                if (e.Exceptions[e.Exceptions.Count - 1] is SqlException ex)
                {
                    Console.WriteLine($"{ex.Number}-{ex.Message}\n");
                }
                else
                {
                    Console.WriteLine($"{e.Exceptions[e.Exceptions.Count - 1].Message}\n");
                }

                // It is not a good practice to do time-consuming tasks inside the retrying event which blocks the running task.
                // Use parallel programming patterns to mitigate it.
                if (e.RetryCount == provider.RetryLogic.NumberOfTries - 1)
                {
                    Console.WriteLine("This is the last chance to execute the command before throwing the exception.");
                    Console.WriteLine("Press Enter when you're ready:");
                    Console.ReadLine();
                    Console.WriteLine("continue ...");
                }
            };

        // Open the general connection.
        s_generalConnection.Open();

        try
        {
            // Assume the database is being created and other services are going to connect to it.
            RetryConnection(provider);
        }
        catch
        {
            // exception is thrown if connecting to the database isn't successful.
            throw;
        }
    }

    private static void ExecuteCommand(SqlConnection cn, string command)
    {
        using var cmd = cn.CreateCommand();
        cmd.CommandText = command;
        cmd.ExecuteNonQuery();
    }

    private static void RetryConnection(SqlRetryLogicBaseProvider provider)
    {
        // Change this if you already have a database with the same name in your database.
        string dbName = "Invalid_DB_Open";

        // Create a connection to an invalid database.
        using var cnn = new SqlConnection(string.Format(CnnStringFormat, dbName));
        // 3. Assign the `provider` to the connection
        cnn.RetryLogicProvider = provider;
        Console.WriteLine($"Connecting to the [{dbName}] ...");
        // Manually execute the following command in SSMS to create the invalid database while the SqlConnection is attempting to connect to it.
        // >> CREATE DATABASE Invalid_DB_Open;
        Console.WriteLine($"Manually, run the 'CREATE DATABASE {dbName};' in the SQL Server before exceeding the {provider.RetryLogic.NumberOfTries} attempts.");
        // the connection tries to connect to the database 5 times
        Console.WriteLine("The first attempt, before getting into the retry logic.");
        cnn.Open();
        Console.WriteLine($"Connected to the [{dbName}] successfully.");

        cnn.Close();

        // Drop it after test
        ExecuteCommand(s_generalConnection, string.Format(DropDatabaseFormat, dbName));
        Console.WriteLine($"The [{dbName}] is removed.");
    }
}
/// Detecting retriable exceptions is a vital part of the retry pattern.
/// Before applying retry logic it is important to investigate exceptions and choose a retry provider that best fits your scenario.
/// First, log your exceptions and find transient faults.
/// The purpose of this sample is to illustrate how to use this feature and the condition might not be realistic.

    private const string DefaultDB = "Northwind";
    private const string CnnStringFormat = "Server=localhost; Initial Catalog={0}; Integrated Security=true; pooling=false;";
    private const string DropDatabaseFormat = "DROP DATABASE {0}";
    private const string CreateDatabaseFormat = "CREATE DATABASE {0}";

    // For general use
    private static SqlConnection s_generalConnection = new SqlConnection(string.Format(CnnStringFormat, DefaultDB));

    static void Main(string[] args)
    {
        // 1. Define the retry logic parameters
        var options = new SqlRetryLogicOption()
        {
            NumberOfTries = 5,
            MaxTimeInterval = TimeSpan.FromSeconds(20),
            DeltaTime = TimeSpan.FromSeconds(1),
            AuthorizedSqlCondition = null,
            // error number 3702 : Cannot drop database "xxx" because it is currently in use.
            TransientErrors = new int[] {3702}
        };

        // 2. Create a retry provider
        var provider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(options);

        // define the retrying event to report execution attempts
        provider.Retrying += (object s, SqlRetryingEventArgs e) =>
            {
                int attempts = e.RetryCount + 1;
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine($"attempt {attempts} - current delay time:{e.Delay} \n");
                Console.ForegroundColor = ConsoleColor.DarkGray;
                if (e.Exceptions[e.Exceptions.Count - 1] is SqlException ex)
                {
                    Console.WriteLine($"{ex.Number}-{ex.Message}\n");
                }
                else
                {
                    Console.WriteLine($"{e.Exceptions[e.Exceptions.Count - 1].Message}\n");
                }

                // It is not good practice to do time-consuming tasks inside the retrying event which blocks the running task.
                // Use parallel programming patterns to mitigate it.
                if (e.RetryCount == provider.RetryLogic.NumberOfTries - 1)
                {
                    Console.WriteLine("This is the last chance to execute the command before throwing the exception.");
                    Console.WriteLine("Press Enter when you're ready:");
                    Console.ReadLine();
                    Console.WriteLine("continue ...");
                }
            };

        // Open a general connection.
        s_generalConnection.Open();

        try
        {
            // Assume the database is creating and other services are going to connect to it.
            RetryCommand(provider);
        }
        catch
        {
            s_generalConnection.Close();
            // exception is thrown if connecting to the database isn't successful.
            throw;
        }
        s_generalConnection.Close();
    }

    private static void ExecuteCommand(SqlConnection cn, string command)
    {
        using var cmd = cn.CreateCommand();
        cmd.CommandText = command;
        cmd.ExecuteNonQuery();
    }

    private static void FindActiveSessions(SqlConnection cnn, string dbName)
    {
        using var cmd = cnn.CreateCommand();
        cmd.CommandText = "DECLARE @query NVARCHAR(max) = '';" + Environment.NewLine +
            $"SELECT @query = @query + 'KILL ' + CAST(spid as varchar(50)) + ';' FROM sys.sysprocesses WHERE dbid = DB_ID('{dbName}')" + Environment.NewLine +
            "SELECT @query AS Active_sessions;";
        var reader = cmd.ExecuteReader();
        if (reader.Read())
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.Write($">> Execute the '{reader.GetString(0)}' command in SQL Server to unblock the running task.");
            Console.ResetColor();
        }
        reader.Close();
    }
var RetryLogicOption = new SqlRetryLogicOption()
{
    NumberOfTries = 5,
    // Declare the error number 102 as a transient error to apply the retry logic when it occurs.
    TransientErrors = new int[] { 102 },
    // When a SqlCommand executes out of a transaction, 
    // the retry logic will apply if it contains a 'select' keyword.
    AuthorizedSqlCondition = x => string.IsNullOrEmpty(x)
            || Regex.IsMatch(x, @"\b(SELECT)\b", RegexOptions.IgnoreCase),
    DeltaTime = TimeSpan.FromSeconds(1),
    MaxTimeInterval = TimeSpan.FromSeconds(60),
    MinTimeInterval = TimeSpan.FromSeconds(3)
};

Кроме того, появились новые разделы конфигурации, позволяющие выполнить регистрацию в файлах конфигурации, не изменяя существующий код:

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

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

Ниже приведен простой пример использования новых разделов конфигурации в файлах конфигурации:

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

Кроме того, в приложении можно реализовать собственный поставщик базового класса SqlRetryLogicBaseProvider и зарегистрировать его с помощью SqlConnection/SqlCommand.

Счетчики событий

Для приложений, предназначенных для .NET Core 3.1 или более поздней версии и .NET Standard 2.1 или более поздней версии, теперь доступны указанные ниже счетчики.

Имя. отображаемое имя; Description
active-hard-connections Фактическое число активных подключений к серверам Количество подключений, открытых в настоящее время к серверам баз данных.
hard-connects Фактическая скорость подключения к серверам Количество подключений в секунду, открываемых серверам баз данных.
hard-disconnects Фактическая скорость отключения от серверов Количество отключений в секунду на серверы баз данных.
active-soft-connects Активные подключения, полученные из пула подключений Количество уже открытых подключений, используемых из пула подключений.
soft-connects Скорость подключений, получаемых из пула подключений Количество подключений в секунду, потребляемых из пула подключений.
soft-disconnects Скорость возврата подключений в пул подключений Количество подключений в секунду, возвращаемое в пул подключений.
number-of-non-pooled-connections Число подключений, не использующих пул подключений Количество активных подключений, не помещаемых в пул.
number-of-pooled-connections Число подключений, управляемых пулом подключений Количество активных подключений, управляемых инфраструктурой пула подключений.
number-of-active-connection-pool-groups Число уникальных активных строк подключения Количество активных, уникальных групп пула подключений. Этот счетчик основан на количестве уникальных строка подключения, найденных в домене приложения.
number-of-inactive-connection-pool-groups Число уникальных строк подключения в очереди на удаление Число уникальных групп пулов подключений, помеченных для обрезки. Этот счетчик основан на количестве уникальных строка подключения, найденных в домене приложения.
number-of-active-connection-pools Число активных пулов подключений Общее число пулов соединений.
number-of-inactive-connection-pools Число неактивных пулов подключений Количество неактивных пулов соединений без недавних действий и ожидание удаления.
number-of-active-connections Число активных подключений. Количество активных подключений, используемых в настоящее время.
number-of-free-connections Число готовых подключений в пуле подключений Количество открытых подключений, доступных в пулах подключений.
number-of-stasis-connections Число подключений, ожидающих подготовки Число подключений, ожидающих завершения действия и недоступных для использования приложением.
number-of-reclaimed-connections Число подключений, освобожденных в результате сборки мусора Количество подключений, восстановленных через сборку мусора, где Close или Dispose не было вызвано приложением. Примечание. Если подключения не закрывать и не удалять явно, производительность может снижаться.

Эти счетчики можно использовать с глобальными средствами CLI .NET Core: dotnet-counters и dotnet-trace в Windows или Linux и PerfView в Windows. При этом в качестве имени поставщика следует указывать Microsoft.Data.SqlClient.EventSource. Дополнительные сведения см. в разделе Получение значений счетчиков событий.

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

Введение зависимости от удостоверений Azure

Microsoft.Data.SqlClient теперь зависит от библиотеки Azure.Identity при получении маркеров для режимов проверки подлинности "Управляемое удостоверение Active Directory/MSI" и "Субъект-служба Active Directory". Это нововведение обуславливает указанные ниже изменения в общедоступной контактной зоне.

  • Критическое изменение
    Для свойства подключения "Идентификатор пользователя" теперь требуется "Идентификатор клиента" вместо "Идентификатора объекта" для управляемого удостоверения, назначаемого пользователем.
  • Общедоступный API
    Новое открытое свойство только для чтения: SqlAuthenticationParameters.ConnectionTimeout
  • Зависимость
    Azure.Identity 1.3.0

Усовершенствования трассировки событий в SNI.dll

Версии Microsoft.Data.SqlClient.SNI (зависимость платформы .NET Framework) и Microsoft.Data.SqlClient.SNI.runtime (зависимость .NET Core/Standard) обновлены до v3.0.0-preview1.21104.2. Трассировка событий в SNI.dll больше не включена через клиентское приложение. Подписывание сеанса поставщику Microsoft.Data.SqlClient.EventSource с помощью таких xperf средств или perfview достаточно. Дополнительные сведения см. в разделе Поддержка трассировки событий в Native SNI.

Включение поведения при значении версии строки — NULL

SqlDataReader возвращает значение DBNull вместо пустого массива byte[]. Чтобы восстановить прежнее поведение, включите параметр AppContext Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior при запуске приложения.

Поддержка проверки подлинности Microsoft Entra по умолчанию

Примечание.

Хотя идентификатор Microsoft Entra — это новое имя Azure Active Directory (Azure AD), чтобы предотвратить нарушение существующих сред, Azure AD по-прежнему остается в некоторых жестко закодированных элементах, таких как поля пользовательского интерфейса, поставщики подключений, коды ошибок и командлеты. В этой статье два имени являются взаимозаменяемыми.

В этом выпуске введен новый метод проверки подлинности SQL: Active Directory по умолчанию. Этот режим проверки подлинности расширяет возможности проверки подлинности пользователей с помощью идентификатора Microsoft Entra, расширяя решения для входа в клиентную среду, Visual Studio Code, Visual Studio, Azure CLI и т. д.

В этом режиме проверки подлинности драйвер получает маркер, передавая DefaultAzureCredential из библиотеки удостоверений Azure для получения маркера доступа. Этот режим пытается использовать эти типы учетных данных для получения маркера доступа в следующем порядке.

  • EnvironmentCredential
    • Включает проверку подлинности с помощью идентификатора Microsoft Entra с помощью клиента и секрета или имени пользователя и пароля, сведения, настроенные в следующих переменных среды: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_CLIENT_CERTIFICATE_PATH, AZURE_USERNAME, AZURE_PASSWORD (дополнительные сведения)
  • ManagedIdentityCredential
    • Пытается выполнить проверку подлинности с помощью идентификатора Microsoft Entra с помощью управляемого удостоверения, назначенного среде развертывания. Идентификатор клиента управляемого удостоверения, назначаемого пользователем, считывается из свойства подключения "Идентификатор пользователя".
  • SharedTokenCacheCredential
    • Проверяет подлинность с использованием токенов в локальном кэше, совместно используемом приложениями Майкрософт.
  • VisualStudioCredential
    • Включение проверки подлинности с помощью идентификатора Microsoft Entra с помощью данных из Visual Studio
  • VisualStudioCodeCredential
    • Включает проверку подлинности с помощью идентификатора Microsoft Entra с помощью данных из Visual Studio Code.
  • AzureCliCredential
    • Включает проверку подлинности с помощью идентификатора Microsoft Entra с помощью Azure CLI для получения маркера доступа.

InteractiveBrowserCredential отключен в реализации драйвера "Active Directory по умолчанию", и "интерактивная проверка подлинности Active Directory" — это единственный вариант, доступный для получения маркера с использованием многофакторной или интерактивной проверки подлинности *.

Дополнительные варианты настройки в данный момент недоступны.

Усовершенствования для регистрации пользовательских поставщиков хранилища главных ключей

Microsoft.Data.SqlClient теперь позволяет лучше контролировать то, где поставщики хранилища главных ключей доступны в приложении, обеспечивая более эффективную поддержку мультитенантных приложений и разрешая применение шифрования и расшифровки столбцов. Чтобы обеспечить регистрацию пользовательских поставщиков хранилища главных ключей в экземплярах SqlConnection и SqlCommand, введены следующие API:

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

Статический API для SqlConnection, SqlConnection.RegisterColumnEncryptionKeyStoreProviders, используемый для глобальной регистрации пользовательских поставщиков хранилища главных ключей, по-прежнему поддерживается. Глобальный кэш ключей шифрования столбцов применяется только к глобально зарегистрированным поставщикам.

Приоритет при регистрации поставщиков хранилища главных ключей для столбцов

Встроенные поставщики хранилища главных ключей столбцов, доступные для хранилища сертификатов Windows, хранилища CNG и CSP, предварительно зарегистрированы. Не следует регистрировать поставщики для экземпляров подключений или команд, если требуется один из встроенных поставщиков хранилища главных ключей для столбцов.

Пользовательские поставщики хранилища главных ключей можно регистрировать в драйвере на трех разных уровнях. Глобальный уровень остался без изменений. Новые регистрации на уровне команд и для каждого подключения пусты изначально и могут быть заданы более одного раза.

Ниже описывается, в какой очередности применяются эти три уровня регистрации:

  • Регистрация каждой команды проверяется, не является ли она пустой.
  • Если регистрация для каждой команды пуста, регистрация для каждого подключения проверяется, не является ли она пустой.
  • Если регистрация на уровне подключения отсутствует, проверяется глобальная регистрация.

Когда любой поставщик хранилища ключей найден на уровне регистрации, драйвер не возвращается к другим регистрациям для поиска поставщика. Если поставщики зарегистрированы, но соответствующий поставщик не найден на уровне, создается исключение, содержащее только зарегистрированных поставщиков в проверке регистрации.

Приоритет кэша ключей шифрования для столбцов

Драйвер не кэширует ключи шифрования столбцов (CEKs) для поставщиков пользовательских хранилищ ключей, зарегистрированных с помощью новых API уровня экземпляра. Для повышения производительности поставщики хранилища ключей должны реализовывать собственный кэш. Драйвер отключает локальный кэш ключей шифрования столбцов, реализованных настраиваемыми поставщиками хранилища ключей, если экземпляр поставщика хранилища ключей зарегистрирован в драйвере на глобальном уровне.

У базового класса SqlColumnEncryptionKeyStoreProvider также появился новый API для установки времени существования кэша:

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

Выбор IP-адреса

Новое свойство подключения IPAddressPreference используется для указания предпочтительного семейства IP-адресов для драйвера при установлении TCP-подключений. Если Transparent Network IP Resolution (в .NET Framework) или Multi Subnet Failover имеет значение true, этот параметр не действует. Для этого свойства используются три допустимых значения:

  • IPv4First

    • Это значение по умолчанию. Сначала драйвер использует разрешенные IPv4-адреса. Если ни один из них не может быть подключен к успешному подключению, он пытается разрешить адреса IPv6.
  • IPv6First

    • Сначала драйвер использует разрешенные IPv6-адреса. Если ни один из них не может быть подключен к успешному подключению, он пытается разрешить адреса IPv4.
  • UsePlatformDefault

    • Драйвер пытается использовать IP-адреса в порядке, полученном из ответа разрешения DNS.

Поддержка целевой платформы 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)

Заметки о выпуске для Microsoft.Data.SqlClient 2.1

Полные заметки о выпуске, в том числе зависимости, доступны в репозитории GitHub: заметки о выпуске 2.1.

Новые возможности в версии 2.1

Кроссплатформенная поддержка для Always Encrypted

В Microsoft.Data.SqlClient версии 2.1 добавлена поддержка Always Encrypted для следующих платформ:

Поддержка Always Encrypted Поддержка Always Encrypted с безопасными анклавами Целевая платформа Версия Microsoft.Data.SqlClient Операционная система
Да Да .NET Framework 4.6+ 1.1.0 и выше Windows
Да Да .NET Core 2.1+ 2.1.0 и выше1 Windows, Linux, macOS
Да Нет2 .NET Standard 2.0 2.1.0 и выше Windows, Linux, macOS
Да Да .NET Standard 2.1 и более поздней версии 2.1.0 и выше Windows, Linux, macOS

Примечание.

1 В версиях Microsoft.Data.SqlClient ниже 2.1 функцию Always Encrypted поддерживает только Windows. 2 .NET Standard 2.0 не поддерживает Always Encrypted с безопасными анклавами.

Проверка подлинности потока кода устройства Microsoft Entra

Microsoft.Data.SqlClient версии 2.1 поддерживает проверку подлинности "Поток кода устройства" с помощью MSAL.NET. Справочная документация. Поток предоставления авторизации устройства OAuth2.0

Пример строки подключения:

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

Следующий API позволяет настраивать механизм обратного вызова для потока кода устройства:

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

Проверка подлинности управляемого удостоверения Microsoft Entra

Microsoft.Data.SqlClient версии 2.1 предоставляет поддержку проверки подлинности Microsoft Entra с помощью управляемых удостоверений.

Режим проверки подлинности поддерживает такие ключевые слова:

  • Active Directory Managed Identity (управляемое удостоверение Active Directory);
  • Active Directory MSI (для совместимости с драйверами MS SQL).

Примеры строк подключения.

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

Улучшения интерактивной проверки подлинности Microsoft Entra

Microsoft.Data.SqlClient версии 2.1 добавляет следующие API для настройки интерактивной проверки подлинности 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

В Microsoft.Data.SqlClient версии 2.1 добавлен новый раздел конфигурации, SqlClientAuthenticationProviders (это клон существующего SqlAuthenticationProviders). Существующий раздел конфигурации SqlAuthenticationProviders также поддерживается для обеспечения обратной совместимости, если определен соответствующий тип.

Этот новый раздел позволяет включать в файлы конфигурации одновременно раздел SqlAuthenticationProviders для System.Data.SqlClient и раздел SqlClientAuthenticationProviders для Microsoft.Data.SqlClient.

Проверка подлинности Microsoft Entra с помощью идентификатора клиента приложения

В Microsoft.Data.SqlClient версии 2.1 добавлена поддержка передачи определяемого пользователем идентификатора клиента приложения в библиотеку проверки подлинности Майкрософт. Идентификатор клиента приложения используется при проверке подлинности с помощью идентификатора Microsoft Entra.

Также добавлены следующие API-интерфейсы:

  1. В ActiveDirectoryAuthenticationProvider добавлен новый конструктор:
    [Применимо ко всем платформам .NET (.NET Framework, .NET Core и .NET Standard)]

    public ActiveDirectoryAuthenticationProvider(string applicationClientId)
    

    Использование:

    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. Добавлено новое свойство конфигурации в SqlAuthenticationProviderConfigurationSection и SqlClientAuthenticationProviderConfigurationSection:
    [Применимо к .NET Framework и .NET Core]

    internal class SqlAuthenticationProviderConfigurationSection : ConfigurationSection
    {
        ...
        [ConfigurationProperty("applicationClientId", IsRequired = false)]
        public string ApplicationClientId => this["applicationClientId"] as string;
    }
    
    // Inheritance
    internal class SqlClientAuthenticationProviderConfigurationSection : SqlAuthenticationProviderConfigurationSection
    { ... }
    

    Использование:

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

Поддержка Классификации данных версии 2

В Microsoft.Data.SqlClient версии 2.1 добавлена поддержка информации "Ранг конфиденциальности" согласно Классификации данных. Доступны следующие API-интерфейсы:

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
}

Идентификатор процесса сервера для активного SqlConnection

В Microsoft.Data.SqlClient версии 2.1 введено новое свойство SqlConnection для активного подключения: ServerProcessId.

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

Поддержка журнала трассировки в собственном SNI

Microsoft.Data.SqlClient версии 2.1 пополняет существующую реализацию SqlClientEventSource возможностью трассировки событий в SNI.dll. Эти события должны собираться таким инструментом, как Xperf.

Трассировка может быть включена, отправив команду SqlClientEventSource , как показано ниже.

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

Свойство строки подключения "Command Timeout" (время ожидания команды)

В Microsoft.Data.SqlClient версии 2.1 введено новое свойство строки подключения "Command Timeout", которое позволяет переопределить стандартное время ожидания (30 секунд). Время ожидания для отдельных команд можно также переопределить с помощью свойства CommandTimeout в команде SqlCommand.

Примеры строк подключения.

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

Удаление символов из собственного SNI

Начиная с Microsoft.Data.SqlClient версии 2.1, мы удалили символы, добавленные в версии 2.0.0, из пакета NuGet Microsoft.Data.SqlClient.SNI.runtime (начиная с версии 2.1.1). Теперь общедоступные символы публикуются на сервере символов Майкрософт для BinSkim и других инструментов, которым требуется доступ к общедоступным символам.

Сопоставление с источником для символов Microsoft.Data.SqlClient

Начиная с Microsoft.Data.SqlClient версии 2.1, символы Microsoft.Data.SqlClient сопоставляются с источником и публикуются на сервере символов Майкрософт. Это позволяет поддерживать расширенную отладку без скачивания исходного кода.

Поддержка целевой платформы 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)

Заметки о выпуске для Microsoft.Data.SqlClient 2.0

Полные заметки о выпуске, в том числе зависимости, доступны в репозитории GitHub: заметки о выпуске 2.0.

Критические изменения в версии 2.0

  • Модификатор доступа для интерфейса поставщика анклава SqlColumnEncryptionEnclaveProvider изменен с public на internal.
  • Константы в классе SqlClientMetaDataCollectionNames были обновлены, чтобы отражать изменения в SQL Server.
  • Теперь драйвер выполняет проверку сертификата сервера, когда целевой СЕРВЕР SQL Server применяет шифрование TLS, которое используется по умолчанию для подключений Azure.
  • SqlDataReader.GetSchemaTable() теперь возвращает пустой DataTable вместо null.
  • Теперь драйвер выполняет округление по десятичной шкале, что соответствует поведению SQL Server. Для обеспечения обратной совместимости с помощью параметра AppContext можно включить предыдущее поведение, когда выполнялось усечение.
  • Для платформа .NET Framework приложений, использующих Microsoft.Data.SqlClient, файлы SNI.dll, ранее скачанные в bin\x86 bin\x64 папкуMicrosoft.Data.SqlClient.SNI.x64.dll, именуются и Microsoft.Data.SqlClient.SNI.x86.dll загружаются в bin каталог.
  • Новые синонимы свойств строка подключения заменяют старые свойства при получении строка подключения для SqlConnectionStringBuilder согласованности. Подробнее

Новые возможности в версии 2.0

В Microsoft.Data.SqlClient 2.0 появились следующие новые возможности.

Устойчивость к сбоям DNS

Теперь драйвер кэширует IP-адреса из каждого успешного подключения к конечной точке SQL Server, поддерживающей эту функцию. Если во время попытки подключения возникает сбой разрешения DNS, драйвер пытается установить подключение с помощью кэшированного IP-адреса для этого сервера, если таковой существует.

Трассировка EventSource

В этом выпуске реализована поддержка записи журналов трассировки событий для отладки приложений. Чтобы записать эти события, клиентские приложения должны ожидать передачи данных о событиях от реализации EventSource для SqlClient.

Microsoft.Data.SqlClient.EventSource

Дополнительные сведения см. в разделе Включение трассировки событий в SqlClient.

Включение управляемых сетей в Windows

Новый параметр AppContext Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows позволяет использовать управляемую реализацию SNI в Windows для тестирования и отладки. Этот переключатель переключает поведение драйвера на использование управляемого SNI в .NET Core 2.1+ и .NET Standard 2.0+ проектов в Windows, устраняя все зависимости от собственных библиотек для библиотек Microsoft.Data.SqlClient.

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

Полный список доступных параметров в драйвере см. в разделе Параметры AppContext в SqlClient.

Включение усечения десятичных чисел

Драйвер округляет масштаб десятичных данных по умолчанию, как и SQL Server. Для обеспечения обратной совместимости можно задать для параметра AppContext Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal значение true.

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

Новые синонимы свойств строки подключения

Для следующих свойств строки подключения были добавлены новые синонимы, чтобы избежать путаницы в свойствах, состоящих более чем из одного слова. Старые имена свойств по-прежнему поддерживаются для обратной совместимости. Но новые свойства строка подключения теперь включаются при получении строка подключения из SqlConnectionStringBuilder.

Существующее свойство строки подключения Новый синоним
ApplicationIntent Назначение приложения
ConnectRetryCount Connect Retry Count
ConnectRetryInterval Connect Retry Interval
PoolBlockingPeriod Pool Blocking Period
MultipleActiveResultSets Multiple Active Result Sets
MultiSubnetFailover Multiple Subnet Failover
TransparentNetworkIPResolution Разрешение IP-адресов прозрачной сети
TrustServerCertificate Надежный сертификат сервера

Свойство SqlBulkCopy RowsCopied

Свойство RowsCopied предоставляет доступ только для чтения к количеству строк, которые были обработаны в текущей операции с массовым копированием. Это значение не обязательно должно быть равно конечному количеству строк, добавляемых в целевую таблицу.

Переопределение открытия соединения

Поведение по умолчанию для SqlConnection.Open() можно переопределить, чтобы отключить 10-секундную задержку и автоматические попытки подключения, активируемые временными ошибками.

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

Примечание.

Обратите внимание, что это переопределение можно применить только к SqlConnection.Open(), а не к SqlConnection.OpenAsync().

Поддержка имени пользователя для интерактивного режима Active Directory

Имя пользователя можно указать в строка подключения при использовании интерактивного режима проверки подлинности Microsoft Entra для платформа .NET Framework и .NET Core.

Задайте имя пользователя, используя идентификатор пользователя или свойство строки подключения UID.

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

Указания порядка для SqlBulkCopy

Для повышения производительности операций массового копирования в таблицах с кластеризованными индексами можно предоставить указания порядка. Дополнительные сведения см. в разделе об операциях массового копирования.

Изменения зависимостей SNI

Microsoft.Data.SqlClient (.NET Core и .NET Standard) в Windows теперь зависят от Microsoft.Data.SqlClient.SNI.runtime вместо runtime.native.System.Data.SqlClient.SNI. Новая зависимость добавляет поддержку платформы ARM в дополнение к поддерживаемым платформам ARM64, x64 и x86 в Windows.

Поддержка целевой платформы 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)

Заметки о выпуске для Microsoft.Data.SqlClient 1.1.0

Полные заметки о выпуске, в том числе зависимости, доступны в репозитории GitHub: заметки о выпуске 1.1.

Новые возможности в версии 1.1

Always Encrypted с безопасными анклавами.

Always Encrypted доступна начиная с Microsoft SQL Server 2016. Безопасные анклавы доступны начиная с Microsoft SQL Server 2019. Чтобы использовать функцию анклава, строки подключения должны включать необходимый протокол и URL-адрес аттестации. Например:

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

Дополнительные сведения см. в разделе:

Поддержка целевой платформы 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)

Заметки о выпуске для Microsoft.Data.SqlClient 1.0

Первоначальный выпуск пространства имен Microsoft.Data.SqlClient предлагает больше функциональных возможностей по сравнению с существующим пространством имен System.Data.SqlClient.

Полные заметки о выпуске, в том числе зависимости, доступны в репозитории GitHub: заметки о выпуске 1.0.

Новые возможности в версии 1.0

Новые возможности по сравнению с .NET Framework 4.7.2 System.Data.SqlClient

  • Классификация данных. Доступна в Базе данных SQL Azure и Microsoft SQL Server 2019.

  • Поддержка UTF-8. Доступна в Microsoft SQL Server 2019.

Новые возможности по сравнению с .NET Core 2.2 System.Data.SqlClient

  • Классификация данных. Доступна в Базе данных SQL Azure и Microsoft SQL Server 2019.

  • Поддержка UTF-8. Доступна в Microsoft SQL Server 2019.

  • Проверки подлинности. Режим проверки подлинности с помощью пароля AD DS.

Классификация данных

Классификация данных предоставляет новый набор API-интерфейсов, которые предоставляют сведения только для чтения о конфиденциальности и классификации данных для объектов, полученных через SqlDataReader, если базовый источник поддерживает эту функцию и содержит метаданные о конфиденциальности и классификации данных. См. пример приложения в разделе Обнаружение и классификация данных в 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
    }
}

Поддержка UTF-8

Поддержка UTF-8 не требует изменения кода приложения. Эти изменения SqlClient оптимизируют связь между клиентом и сервером, когда сервер поддерживает UTF-8, а базовым параметром сортировки столбца является UTF-8. См. раздел о UTF-8 в статье Новые возможности SQL Server 2019.

Always Encrypted с безопасными анклавами

В целом, существующая документация, использующая System.Data.SqlClient на .NET Framework и встроенные поставщики хранилища главных ключей столбцов, теперь должны также работать с .NET Core.

Разработка с использованием постоянного шифрования с поставщиком данных .NET Framework

Always Encrypted: защита конфиденциальных данных и хранение ключей шифрования в хранилище сертификатов Windows

Проверка подлинности

С помощью параметра строки подключения Аутентификация можно указать различные режимы проверки подлинности. Дополнительные сведения см. в документации по SqlAuthenticationMethod.

Примечание.

Настраиваемые поставщики хранилища ключей, например поставщик Azure Key Vault, необходимо обновить, чтобы они поддерживали Microsoft.Data.SqlClient. Также для поддержки Microsoft.Data.SqlClient необходимо обновить поставщики анклава. Always Encrypted поддерживается только для целевых объектов .NET Framework и .NET Core. Функция не поддерживается для .NET Standard, поскольку в .NET Standard отсутствуют определенные зависимости шифрования.

Поддержка целевой платформы 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)