Используйте Microsoft. Data.SqlClient в приложении .NET

В этом быстром старте вы создаёте консольное приложение .NET, которое:

  • Считывает строку подключения из переменных среды, а не из исходного кода.
  • Открывает соединение асинхронно.
  • Создаёт таблицу, если её не существует.
  • Вставляет строку с параметризованной командой.
  • Читает строки с параметризованным запросом.
  • Обрабатывает ошибки SQL и отмены.

Пример использует Microsoft. Data.SqlClient 7.0.3, текущий стабильный релиз.

Prerequisites

Вам нужен .NET 10 SDK или более поздний поддерживаемый .NET SDK.

Создание базы данных 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.0.3
dotnet add package Microsoft.Data.SqlClient.Extensions.Azure --version 7.0.3

Пакет расширения предоставляет режимы аутентификации Microsoft Entra ID, предоставляемые драйвером. Приложение, использующее только интегрированную аутентификацию Windows или SQL, может опустить Microsoft.Data.SqlClient.Extensions.Azure.

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

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

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

Fabric SQL или Azure SQL с аутентификацией без пароля

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

az login

Скопируйте точные имена серверов и баз данных из элемента базы данных SQL в Fabric или базе данных Azure SQL. Для 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, которое подключается к Azure SQL, предайте доступ к его управляемой идентификационной базе данных, затем используйте Authentication=Active Directory Managed Identity. Для других вариантов Microsoft Entra ID см. раздел аутентификации Microsoft Entra ID.

SQL Server по TCP

Используйте сервер, порт, базу данных и данные для входа из существующего SQL Server или из руководства по настройке, которому вы следовали. Следующий пример SQL-аутентификации предназначен для локального контейнера разработки. Для 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.

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

Добавление кода приложения

Замените содержимое 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;
        """;

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

    int insertedId;
    using (var insertCommand =
        new SqlCommand(insertSql, connection) { CommandTimeout = 30 })
    {
        insertCommand.Parameters.Add(
            new SqlParameter("@message", SqlDbType.NVarChar, 200)
            {
                Value = "Hello from Microsoft.Data.SqlClient"
            });

        object? result =
            await insertCommand.ExecuteScalarAsync(cancellation.Token);
        insertedId = Convert.ToInt32(result);
    }

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

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

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

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

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

Типы и размеры параметров совпадают с столбцами таблицы. Параметры отправляют значения отдельно от SQL-текста, что предотвращает изменение синтаксиса команд и помогает SQL Server повторно использовать планы запросов.

await using освобождает считыватель и соединение даже в случае возникновения исключения. Удаление соединения возвращает физическое соединение в пул соединений, вместо того чтобы держать одно соединение открытым на протяжении всего срока существования приложения.

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

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

dotnet run

Приложение выводит строку, которую оно вставило:

1: Hello from Microsoft.Data.SqlClient at <timestamp>

Значение идентичности и временная метка различаются в каждой базе данных.

Если не удаётся установить соединение, используйте номер ошибки SQL и идентификатор клиентского соединения из сообщения об ошибке. Проверьте имена серверов и баз данных, доступ к сети, права доступа к базе данных, настройку аутентификации и конфигурацию сертификатов. Не добавляйте TrustServerCertificate=true к Azure SQL или рабочему подключению в качестве универсального способа устранения проблем с подключением.

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

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

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

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