Краткое руководство: подключение и выполнение запросов с помощью Microsoft.Data.SqlClient

В этом кратком руководстве вы создадите консольное приложение .NET с Microsoft.Data.SqlClient 7.1.1.

Вы начинаете с пустой папки, .NET SDK и базы данных SQL Server или Azure SQL, к которой можно получить доступ с компьютера. В итоге вы получаете консольное приложение, которое создаёт таблицу, вставляет две строки с параметрами и читает их обратно.

По пути приложение:

  • Считывает свою строка подключения из переменной среды вместо исходного кода.
  • Открывает соединение асинхронно.
  • Использует параметры для каждого значения, которое отправляет в базу данных.
  • Обрабатывает ошибки SQL и отмену.

Чтобы интегрировать тот же доступ к данным в веб-API, см. раздел Quickstart: Use Microsoft.Data.SqlClient в приложении ASP.NET Core. Используется та же таблица.

Prerequisites

  • SDK .NET 10 или более поздняя поддерживаемая версия SDK .NET. SDK работает на Windows, Linux и macOS. SDK также создаёт версию сэмпла для .NET Framework, которая работает только на Windows и требует .NET Framework 4.8.1. Используйте версию .NET для новых разработок.
  • Редактор кода. Вы можете использовать Visual Studio, Visual Studio Code или любой другой редактор вместе с .NET CLI. В этой статье используется CLI .NET.
  • База данных, к которой можно подключиться. Если у вас его нет, создайте его, используя следующие варианты.

Создание базы данных SQL

Создайте или подключитесь к SQL-базе данных на одной из следующих платформ:

Разрешения базы данных

Приложение создаёт собственную таблицу, так что вам не нужны тестовые данные. Для удостоверения базы данных необходимы разрешения на подключение, а также на создание таблицы, вставку данных в таблицу и выборку данных из таблицы.

Для SQL базы данных в Microsoft Fabric скопируйте имена серверов и баз данных из элемента базы данных SQL. Не используйте SQL analytics endpoint. Учетной записи необходимо разрешение на чтение элемента, которое может быть предоставлено ролью в рабочей области или разрешением на элемент. Для получения дополнительной информации см. раздел «Аутентификация в базе данных SQL». SQL-аутентификация не поддерживается.

Для База данных SQL Azure настройте аутентификацию Microsoft Entra ID и доступ к базе данных.

Создание проекта

В пустой папке выполните следующие команды:

dotnet new console --framework net10.0 --name SqlClientQuickstart
cd SqlClientQuickstart
dotnet add package Microsoft.Data.SqlClient --version 7.1.1
dotnet add package Microsoft.Data.SqlClient.Extensions.Azure --version 7.1.1

Пакет расширения предоставляет драйверу режимы аутентификации Microsoft Entra, такие как Active Directory Default. Если ваше приложение использует только SQL-аутентификацию или интегрированную аутентификацию Windows, вы можете её Microsoft.Data.SqlClient.Extensions.Azureопустить. Когда используете оба пакета, оставляйте их версии одинаковыми. Для других вариантов установки смотрите раздел Установка, обновление и развертывание Microsoft.Data.SqlClient.

Настройте соединение

Задайте SQL_CONNECTION_STRING переменную среды для вашей базы данных. Не добавляйте пароль, токен доступа или production строка подключения в исходный код.

Выберите одну из этих отправных точек и замените заполнители.

Azure SQL или база данных SQL в Fabric с Microsoft Entra ID

Войдите с учетной записью Microsoft Entra, имеющей доступ к базе данных. Для локальной разработки используйте инструмент разработчика, например Azure CLI:

az login

Скопируйте точное имя сервера и базы данных из базы данных Azure SQL или из элемента базы данных SQL в Fabric. Для PowerShell:

$env:SQL_CONNECTION_STRING = 'Server=tcp:<server>,1433;Database=<database>;Authentication=Active Directory Default;Encrypt=Strict;MultiSubnetFailover=true;Connect Timeout=30'

Для Bash:

export SQL_CONNECTION_STRING='Server=tcp:<server>,1433;Database=<database>;Authentication=Active Directory Default;Encrypt=Strict;MultiSubnetFailover=true;Connect Timeout=30'

Для приложения, размещённого в Azure, предоставьте управляемой идентичности приложения доступ к базе данных, затем используйте Authentication=Active Directory Managed Identity. Для других вариантов см. аутентификация Microsoft Entra с Microsoft. Data.SqlClient.

SQL Server с SQL-аутентификацией

Используйте сервер, порт, базу данных и логин для вашего экземпляра SQL Server. Следующий пример — для локального экземпляра разработки, который не имеет доверенного сертификата. Для PowerShell:

$env:SQL_CONNECTION_STRING = 'Server=tcp:<server>,1433;Database=<database>;User ID=<user-id>;Password=<password>;Encrypt=true;TrustServerCertificate=true;Connect Timeout=30'

Для Bash:

export SQL_CONNECTION_STRING='Server=tcp:<server>,1433;Database=<database>;User ID=<user-id>;Password=<password>;Encrypt=true;TrustServerCertificate=true;Connect Timeout=30'

Caution

TrustServerCertificate=true пропускает проверку сертификатов сервера. Используйте его только с локальным экземпляром разработки, у которого нет доверенного сертификата. Для общих или производственных экземпляров SQL Server установите сертификат, которому клиент доверяет, используйте имя сервера на этом сертификате и удалите TrustServerCertificate=true. Для получения дополнительной информации см. Шифрование и проверка сертификатов в Microsoft.Data.SqlClient.

Если ваша среда поддерживает интегрированную аутентификацию Windows или Kerberos, замените User ID и Password на Integrated Security=true. Для требований к установке см. SQL Server и проверка подлинности Windows.

Добавление кода

Замените содержимое Program.cs на следующий код:

using System.Data;
using Microsoft.Data.SqlClient;

string? connectionString =
    Environment.GetEnvironmentVariable("SQL_CONNECTION_STRING");

if (string.IsNullOrWhiteSpace(connectionString))
{
    Console.Error.WriteLine(
        "Set the SQL_CONNECTION_STRING environment variable.");
    return 1;
}

using var cancellation = new CancellationTokenSource();
Console.CancelKeyPress += (_, eventArgs) =>
{
    eventArgs.Cancel = true;
    cancellation.Cancel();
};

try
{
    await using var connection = new SqlConnection(connectionString);
    await connection.OpenAsync(cancellation.Token);

    const string createTableSql = """
        IF OBJECT_ID(N'dbo.SqlClientQuickstart', N'U') IS NULL
        BEGIN
            CREATE TABLE dbo.SqlClientQuickstart
            (
                Id int IDENTITY(1, 1) PRIMARY KEY,
                Message nvarchar(200) NOT NULL,
                CreatedAt datetimeoffset NOT NULL
                    CONSTRAINT DF_SqlClientQuickstart_CreatedAt
                    DEFAULT sysdatetimeoffset()
            );
        END;
        """;

    await using (var createCommand =
        new SqlCommand(createTableSql, connection) { CommandTimeout = 30 })
    {
        await createCommand.ExecuteNonQueryAsync(cancellation.Token);
    }

    const string insertSql = """
        INSERT INTO dbo.SqlClientQuickstart (Message)
        OUTPUT INSERTED.Id
        VALUES (@message);
        """;

    string[] messages =
    [
        "Hello from Microsoft.Data.SqlClient",
        "Parameters keep values out of the SQL text"
    ];

    int firstId = 0;
    await using (var insertCommand =
        new SqlCommand(insertSql, connection) { CommandTimeout = 30 })
    {
        SqlParameter messageParameter =
            insertCommand.Parameters.Add("@message", SqlDbType.NVarChar, 200);

        foreach (string message in messages)
        {
            messageParameter.Value = message;
            int id = (int)(await insertCommand.ExecuteScalarAsync(
                cancellation.Token))!;
            Console.WriteLine($"Inserted row {id}.");
            firstId = firstId == 0 ? id : firstId;
        }
    }

    const string querySql = """
        SELECT Id, Message, CreatedAt
        FROM dbo.SqlClientQuickstart
        WHERE Id >= @firstId
        ORDER BY Id;
        """;

    await using var queryCommand =
        new SqlCommand(querySql, connection) { CommandTimeout = 30 };
    queryCommand.Parameters.Add("@firstId", SqlDbType.Int).Value = firstId;

    await using SqlDataReader reader =
        await queryCommand.ExecuteReaderAsync(cancellation.Token);

    while (await reader.ReadAsync(cancellation.Token))
    {
        Console.WriteLine(
            $"{reader.GetInt32(0)}: {reader.GetString(1)} " +
            $"(created {reader.GetDateTimeOffset(2):u})");
    }

    return 0;
}
catch (OperationCanceledException)
{
    Console.Error.WriteLine("The operation was canceled.");
    return 2;
}
catch (SqlException ex)
{
    Console.Error.WriteLine(
        $"SQL error {ex.Number}, connection {ex.ClientConnectionId}: " +
        ex.Message);
    if (ex.InnerException is not null)
    {
        Console.Error.WriteLine(ex.InnerException.Message);
    }
    return 3;
}

Запуск приложения

Запустите приложение:

dotnet run

При первом запуске приложения таблица пуста, а вывод выглядит так:

Inserted row 1.
Inserted row 2.
1: Hello from Microsoft.Data.SqlClient (created 2026-10-20 20:56:10Z)
2: Parameters keep values out of the SQL text (created 2026-10-20 20:56:10Z)

Ваши временные метки различаются. Каждый следующий запуск добавляет ещё две строки, так что идентификаторы продолжаются с последнего запуска.

Если приложение не может подключиться, оно печатает номер ошибки SQL, идентификатор подключения клиента, сообщение об ошибке и внутреннее сообщение исключения, а затем выходит с кодом 3. О распространённых ошибках см. раздел Устранение неполадок.

Как работает код

  • OpenAsync, ExecuteNonQueryAsync, ExecuteScalarAsync, ExecuteReaderAsync, и ReadAsync все получают один и тот же CancellationToken. Нажмите Ctrl+C, чтобы отменить текущую работу.
  • Команда вставки создаётся один раз и выполняется один раз для каждого сообщения. Меняется только значение параметра.
  • Типы и размеры параметров совпадают с столбцами таблицы. Параметры отправляют значения отдельно от SQL-текста, что не позволяет этим значениям изменять текст команды и помогает SQL Server повторно использовать планы запросов.
  • OUTPUT INSERTED.Id возвращает новое значение идентификатора, то есть ExecuteScalarAsync возвращает ID без второго запроса.
  • await using освобождает команды, считыватель и соединение, даже если возникает исключение. Освобождение соединения возвращает его в пул соединений. Версия .NET Framework использует блоки using, потому что эти типы не реализуют IAsyncDisposable в .NET Framework.
  • SqlException.Number Он определяет ошибку и ClientConnectionId позволяет сопоставить сбой клиента с серверными логами. Для сбоев соединения на Linux и macOS причина часто заключается только в InnerException, например, в сбое проверки сертификата, скрытом за общим сообщением error: 35 - An internal exception was caught.

Troubleshoot

Ошибка или симптом Что требуется проверить Дополнительная информация
The certificate chain was issued by an authority that is not trustedна Windows. На Linux и macOS error: 35 - An internal exception was caught, затем следует внутреннее исключение Certificate failed chain validation с UntrustedRoot. Клиент не доверяет сертификату сервера, или имя сервера в строке подключения не совпадает с именем в сертификате. Установите доверенный сертификат. Используйте TrustServerCertificate=true только с локальным экземпляром разработки. Шифрование и проверка сертификатов в Microsoft. Data.SqlClient
SQL error 18456 С Login failed for user Имя пользователя, пароль или имя базы данных неверны, или логин не имеет доступа к базе данных. Для Microsoft Entra ID проверьте, была ли учетная запись добавлена как пользователь базы данных. Руководство по устранению неполадок с SqlClient
A network-related or instance-specific error occurred с error: 26, error: 40или The wait operation timed out. На Linux и macOS тайм-аут показывается SQL error 258 с error: 35, за которым следует внутреннее исключение The connection attempt timed out. Имя сервера или порт неверны, сервер не принимает удалённые TCP-соединения, или межсетевой экран блокирует порт. Для Azure SQL проверьте правила серверного файрвола. Руководство по устранению неполадок с SqlClient
System.ArgumentException: Cannot find an authentication provider for 'ActiveDirectoryDefault' Строка строка подключения использует режим аутентификации Active Directory, но проект не ссылается на Microsoft.Data.SqlClient.Extensions.Azure. Добавьте пакет той же версии, что и Microsoft.Data.SqlClient. Аутентификация Microsoft Entra переходит в пакет расширения в версии 7.0
CS0234: The type or namespace name 'Data' does not exist in the namespace 'Microsoft' Проект не ссылается на пакет Microsoft.Data.SqlClient . Запустите dotnet add package команду из папки, содержащей файл проекта. Установка, обновление и развертывание Microsoft. Data.SqlClient
Отчёты о восстановлении NU1902 или NU1903 для транзитивного пакета Пакет, от которого зависит драйвер, имеет опубликованное предупреждение. Действия при сообщении о пакетах с известными уязвимостями

Очистите ресурсы

Таблица остаётся в вашей базе данных после выхода приложения. Если вы не планируете продолжать работу с кратким руководством по ASP.NET Core, в котором используется та же таблица, удалите её с помощью любого инструмента запросов:

DROP TABLE IF EXISTS dbo.SqlClientQuickstart;

Затем удалите папку проекта. В родительской папке для PowerShell:

Remove-Item -Recurse -Force SqlClientQuickstart

Для Bash:

rm -rf SqlClientQuickstart

Очистите переменную окружения, чтобы строка подключения не оставалась в вашей shell-сессии. Для PowerShell запускайте Remove-Item Env:\SQL_CONNECTION_STRING. Для Bash, выполните unset SQL_CONNECTION_STRING.

Используйте шаблон в приложении

Сохраняйте эти границы при переносе образца в API, сервис, десктопное приложение или фоновый рабочий элемент:

  • Загрузите информацию о подключении через систему конфигурации приложения.
  • Откройте одно соединение для выполнения небольшой операции, а затем закройте его.
  • Передайте CancellationToken в вызовы open, command и reader.
  • Устанавливайте тайм-ауты команд в зависимости от операции.
  • Используйте параметры для каждого значения, полученного вне SQL-оператора.
  • Записывайте в журнал SqlException.Number и ClientConnectionId, не записывая в журнал учетные данные или токены доступа.
  • Добавляйте повторные попытки только при временных сбоях и только если повторное выполнение операции безопасно.

Дальнейшие действия