Użyj Microsoft. Data.SqlClient w aplikacji .NET

W tym szybkim starcie tworzysz aplikację konsolową .NET, która:

  • Odczytuje parametry połączenia ze środowiska zamiast z kodu źródłowego.
  • Otwiera połączenie asynchronicznie.
  • Tworzy tabelę, jeśli nie istnieje.
  • Wstawia wiersz za pomocą parametryzowanego polecenia.
  • Odczytuje wiersze za pomocą parametryzowanego zapytania.
  • Obsługuje błędy SQL i anulowania.

Przykład wykorzystuje Microsoft. Data.SqlClient 7.0.3, aktualna stabilna wersja.

Wymagania wstępne

Potrzebujesz SDK .NET 10 lub później obsługiwanego SDK .NET.

Tworzenie bazy danych SQL

Stwórz lub połącz się z bazą danych SQL na jednej z następujących platform:

Quickstart tworzy własną tabelę, więc próbki danych nie są potrzebne. Tożsamość bazy danych musi mieć uprawnienia do nawiązywania połączenia oraz do tworzenia tabeli, wstawiania do niej danych i wybierania z niej danych.

Dla bazy danych SQL w Microsoft Fabric skopiuj nazwy serwerów i baz danych z elementu bazy SQL. Nie używaj endpointu analityki SQL. Ta tożsamość wymaga uprawnienia do odczytu elementu, które może zapewnić rola obszaru roboczego lub uprawnienie do elementu. Więcej informacji można znaleźć w artykule Uwierzytelnianie w bazie danych SQL. Uwierzytelnianie SQL nie jest obsługiwane.

Dla Azure SQL Database konfiguruj uwierzytelnianie Microsoft Entra ID i dostęp do bazy danych.

Tworzenie projektu

Uruchom te polecenia:

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

Pakiet rozszerzenia zapewnia tryby uwierzytelniania Microsoft Entra ID dostarczane przez sterowniki. Aplikacja korzystająca wyłącznie z uwierzytelniania zintegrowanego z systemem Windows lub uwierzytelniania SQL może pominąć Microsoft.Data.SqlClient.Extensions.Azure.

Konfiguruj połączenie

Ustaw zmienną środowiskową SQL_CONNECTION_STRING dla swojej bazy danych. Nie umieszczaj hasła, tokena dostępu ani production parametry połączenia w kodzie źródłowym.

Wybierz jeden z tych punktów wyjścia i zastąp symbole zastępcze.

Fabric SQL lub Azure SQL z uwierzytelnianiem bez hasła

Zaloguj się za pomocą tożsamości w Microsoft Entra ID, która ma dostęp do bazy danych. Do lokalnego rozwoju korzystaj z narzędzia deweloperskiego, takiego jak Azure CLI:

az login

Skopiuj dokładne nazwy serwerów i baz danych z elementu SQL w Fabric lub Azure SQL. Dla PowerShell:

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

Dla Bash:

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

Dla aplikacji hostowanej w Azure, która łączy się z Azure SQL, przyznaj jej dostęp do bazy danych zarządzanej tożsamości, a następnie użyj Authentication=Active Directory Managed Identity. Aby poznać inne opcje Microsoft Entra ID, zobacz Microsoft Entra ID uwierzytelnianie.

SQL Server przez TCP

Użyj serwera, portu, bazy danych i loginu z istniejącego serwera SQL Server lub z przewodnika konfiguracji, z którego korzystałeś. Poniższy przykład uwierzytelniania SQL dotyczy lokalnego kontenera deweloperskiego. Dla PowerShell:

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

Dla 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 pomija walidację certyfikatów serwera. Używaj tego tylko z lokalną instancją programistyczną, która nie ma zaufanego certyfikatu. Dla współdzielonych lub produkcyjnych instancji SQL Server zainstaluj certyfikat, któremu klient ufa, użyj nazwy serwera na tym certyfikcie i usuń TrustServerCertificate=true.

Jeśli środowisko obsługuje uwierzytelnianie zintegrowane z Windows lub Kerberos, zastąp User ID i Password na Integrated Security=true. Wymagania dotyczące konfiguracji znajdziesz w artykule SQL Server Authentication.

Dodawanie kodu aplikacji

Zastąp zawartość Program.cs tego kodu następującym kodem:

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

Typy i rozmiary parametrów odpowiadają kolumnom tabeli. Parametry wysyłają wartości oddzielnie od tekstu SQL, co zapobiega zmianie składni poleceń i pomaga SQL Server ponownie wykorzystać plany zapytań.

await using eliminuje czytelnika i połączenie nawet wtedy, gdy wystąpi wyjątek. Zamknięcie połączenia powoduje zwrócenie jego fizycznego połączenia do puli połączeń, zamiast utrzymywać jedno połączenie otwarte przez cały czas działania aplikacji.

Uruchamianie aplikacji

Uruchom aplikację:

dotnet run

Aplikacja drukuje wiersz, który wstawiła:

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

Wartość tożsamości i znacznik czasu różnią się w każdej bazie danych.

Jeśli połączenie się nie powiedzie, użyj numeru błędu SQL i identyfikatora połączenia klienta z wyniku błędu. Sprawdź nazwy serwerów i baz danych, dostęp do sieci, uprawnienia do bazy danych, konfigurację uwierzytelniania oraz konfigurację certyfikatów. Nie dodawaj TrustServerCertificate=true do połączenia z Azure SQL ani do połączenia produkcyjnego jako uniwersalnego rozwiązania problemów z połączeniem.

Wykorzystaj ten wzór w aplikacji

Zachowaj te granice, gdy przenosisz próbkę do API, usługi, aplikacji desktopowej lub pracownika w tle:

  • Ładuj informacje o połączeniach przez system konfiguracyjny aplikacji.
  • Otwórz jedno połączenie na czas krótkiej operacji, a następnie je zamknij.
  • Przekaż element CancellationToken przez wywołania open, command i reader.
  • Ustaw limity czasowe poleceń w zależności od operacji.
  • Używaj parametrów dla każdej wartości pochodzącej spoza instrukcji SQL.
  • Rejestruj ClientConnectionId i SqlException.Number bez rejestrowania poświadczeń ani tokenów dostępu.
  • Dodawaj powtórki tylko przy przejściowych awariach i tylko wtedy, gdy powtarzanie operacji jest bezpieczne.

Następne kroki