Szybki start: Połącz się i wykonuj zapytania za pomocą Microsoft.Data.SqlClient

W tym przewodniku Szybki start tworzysz aplikację konsolową .NET z Microsoft.Data.SqlClient 7.1.1.

Zaczynasz od pustego folderu, SDK .NET oraz bazy danych SQL Server lub Azure SQL, do której masz dostęp z komputera. Kończysz z aplikacją konsolową, która tworzy tabelę, wstawia dwa wiersze z parametrami i odczytuje je z powrotem.

Aplikacja po drodze:

  • Odczytuje swój parametry połączenia ze zmiennej środowiskowej zamiast z kodu źródłowego.
  • Otwiera połączenie asynchronicznie.
  • Wykorzystuje parametry dla każdej wartości, którą wysyła do bazy danych.
  • Obsługuje błędy SQL i anulowanie.

Aby wbudować ten sam dostęp do danych w internetowym interfejsie API, zobacz Szybki start: używanie Microsoft.Data.SqlClient w aplikacji ASP.NET Core. Używa tej samej tabeli.

Wymagania wstępne

  • SDK .NET 10 lub nowszy obsługiwany pakiet SDK platformy .NET. SDK działa na Windows, Linux i macOS. SDK buduje także wersję .NET Framework tego przykładu, która działa tylko w systemie Windows i wymaga .NET Framework 4.8.1. W przypadku nowych projektów używaj wersji .NET.
  • Edytor kodu. Możesz używać Visual Studio, Visual Studio Code lub dowolnego edytora razem z .NET CLI. Ten artykuł korzysta z CLI .NET.
  • Baza danych, z którą możesz się połączyć. Jeśli go nie masz, stwórz je, korzystając z poniższych opcji.

Tworzenie bazy danych SQL

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

Uprawnienia bazy danych

Aplikacja tworzy własną tabelę, więc nie potrzebujesz danych próbnych. 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

W pustym folderze wykonaj następujące polecenia:

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

Pakiet rozszerzenia zapewnia tryby uwierzytelniania sterownika Microsoft Entra, takie jak Active Directory Default. Jeśli Twoja aplikacja używa tylko uwierzytelniania SQL lub zintegrowanego uwierzytelniania Windows, możesz pominąć Microsoft.Data.SqlClient.Extensions.Azure. Gdy używasz obu pakietów, utrzymuj wersje obu pakietów takie same. Inne opcje instalacji znajdziesz w artykule Instalowanie, aktualizowanie i wdrażanie Microsoft.Data.SqlClient.

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.

Azure SQL lub baza danych SQL w usłudze Fabric z identyfikatorem Microsoft Entra ID

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

az login

Skopiuj dokładną nazwę serwera i nazwę bazy danych z bazy danych Azure SQL lub elementu bazy danych SQL w usłudze Fabric. 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 przyznaj jej zarządzanej tożsamości dostęp do bazy danych, a następnie użyj Authentication=Active Directory Managed Identity. Informacje o innych opcjach można znaleźć tutaj: Microsoft Entra authentication with Microsoft.Data.SqlClient.

SQL Server z uwierzytelnianiem SQL

Użyj serwera, portu, bazy danych i nazwy użytkownika dla swojej instancji SQL Server. Poniższy przykład dotyczy lokalnej instancji deweloperskiej, która nie posiada zaufanego certyfikatu. 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. Aby uzyskać więcej informacji, zapoznaj się z Encryption and certificate validation in Microsoft.Data.SqlClient.

Jeśli Twoje środowisko obsługuje zintegrowane uwierzytelnianie systemu Windows lub protokół Kerberos, zamień User ID i Password na Integrated Security=true. Wymagania dotyczące konfiguracji można znaleźć w sekcji SQL Server i uwierzytelnianie systemu Windows.

Dodawanie kodu

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

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

Uruchom aplikację

Uruchom aplikację:

dotnet run

Za pierwszym uruchomieniem aplikacji tabela jest pusta, a wyjście wygląda tak:

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)

Twoje znaczniki czasowe się różnią. Każdy kolejny przebieg dodaje dwa kolejne wiersze, więc identyfikatory są kontynuowane od ostatniego przebiegu.

Jeśli aplikacja nie może się połączyć, drukuje numer błędu SQL, identyfikator połączenia klienta, komunikat o błędzie oraz komunikat wyjątku wewnętrznego, a następnie kończy z kodem 3. W przypadku typowych błędów zobacz Rozwiązywanie problemów.

Jak działa kod

  • OpenAsync, ExecuteNonQueryAsync, ExecuteScalarAsync, ExecuteReaderAsync i ReadAsync wszystkie otrzymują to samo CancellationToken. Naciśnij Ctrl+C, aby anulować pracę w toku.
  • Polecenie insert jest tworzone raz i jest uruchamiane raz dla każdej wiadomości. Zmienia się tylko wartość parametru.
  • Typy i rozmiary parametrów odpowiadają kolumnom tabeli. Parametry przesyłają wartości oddzielnie od tekstu SQL, co zapobiega zmianie polecenia przez te wartości i pomaga SQL Server ponownie wykorzystać plany zapytań.
  • OUTPUT INSERTED.Id zwraca nową wartość tożsamościową, więc ExecuteScalarAsync zwraca ID bez drugiego zapytania.
  • await using zamyka i zwalnia zasoby poleceń, obiektu odczytującego i połączenia, nawet gdy występuje wyjątek. Zwolnienie połączenia zwraca je do puli połączeń. Wersja .NET Framework wykorzystuje bloki using, ponieważ te typy nie implementują IAsyncDisposable w środowisku .NET Framework.
  • SqlException.Number identyfikuje błąd i ClientConnectionId pozwala dopasować awarię klienta do logów po stronie serwera. W przypadku awarii połączenia w systemach Linux i macOS przyczyna często leży tylko w InnerException, na przykład w awarii walidacji certyfikatu ukrytej za ogólnym error: 35 - An internal exception was caught.

Troubleshoot

Błąd lub objaw Co należy sprawdzić? Więcej informacji
The certificate chain was issued by an authority that is not trusted w systemie Windows. W systemach Linux i macOS, error: 35 - An internal exception was caught, po którym następuje wewnętrzny wyjątek Certificate failed chain validation z UntrustedRoot. Certyfikat serwera nie jest zaufany przez klienta lub nazwa serwera w parametry połączenia nie zgadza się z certyfikatem. Zainstaluj zaufany certyfikat. Używaj TrustServerCertificate=true tylko z lokalną instancją deweloperską. Szyfrowanie i walidacja certyfikatów w Microsoft. Data.SqlClient
SQL error 18456 Z Login failed for user Nazwa użytkownika, hasło lub nazwa bazy danych są błędne albo konto nie ma dostępu do bazy. Dla Microsoft Entra ID sprawdź, czy tożsamość została dodana jako użytkownik bazy danych. Przewodnik rozwiązywania problemów z programem SqlClient
A network-related or instance-specific error occurred z error: 26, error: 40, lub The wait operation timed out. W systemach Linux i macOS wyświetlany jest limit czasu SQL error 258 z error: 35, po którym następuje wyjątek wewnętrzny The connection attempt timed out. Nazwa serwera lub port jest błędny, serwer nie akceptuje zdalnych połączeń TCP lub zapora sieciowa blokuje port. Dla Azure SQL sprawdź reguły zapory serwerowej. Przewodnik rozwiązywania problemów z programem SqlClient
System.ArgumentException: Cannot find an authentication provider for 'ActiveDirectoryDefault' Ciąg połączenia używa trybu uwierzytelniania Active Directory, ale projekt nie odwołuje się do Microsoft.Data.SqlClient.Extensions.Azure. Dodaj pakiet z tą samą wersją co Microsoft.Data.SqlClient. Uwierzytelnianie Microsoft Entra przechodzi do pakietu rozszerzeniowego w wersji 7.0
CS0234: The type or namespace name 'Data' does not exist in the namespace 'Microsoft' Projekt nie odnosi się do pakietu Microsoft.Data.SqlClient . Uruchom dotnet add package polecenie z folderu, w którym znajduje się plik projektu. Zainstaluj, aktualizuj i wdrażaj Microsoft. Data.SqlClient
Przywróć raporty NU1902 lub NU1903 dla pakietu przechodniego Pakiet, od którego zależy sterownik, zawiera opublikowany komunikat. Działania, gdy zgłoszono pakiety ze znanymi podatnościami

Uprzątnij zasoby

Tabela pozostaje w twojej bazie danych po zamknięciu aplikacji. Jeśli nie planujesz kontynuować szybkiego startu ASP.NET Core, który korzysta z tej samej tabeli, usuń ją za pomocą dowolnego narzędzia zapytań:

DROP TABLE IF EXISTS dbo.SqlClientQuickstart;

Następnie usuń folder projektu. Z folderu nadrzędnego, dla PowerShell:

Remove-Item -Recurse -Force SqlClientQuickstart

Dla Bash:

rm -rf SqlClientQuickstart

Usuń zmienną środowiskową, żeby parametry połączenia nie pozostał w sesji shell. Dla PowerShell użyj Remove-Item Env:\SQL_CONNECTION_STRING. W Bashu uruchom unset SQL_CONNECTION_STRING.

Wykorzystaj ten wzór w aplikacji

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

  • Ładuj informacje o połączeniu przez system konfiguracji 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