Usa Microsoft.Data.SqlClient in un'app .NET

In questo avvio rapido, crei un'applicazione console .NET che:

  • Legge la sua stringa di connessione dall'ambiente invece che dal codice sorgente.
  • Apre una connessione in modo asincrono.
  • Crea una tabella se non esiste.
  • Inserisce una riga con un comando parametrizzato.
  • Legge le righe con una query parametrizzata.
  • Gestisce gli errori SQL e di cancellazione.

L'esempio utilizza Microsoft. Data.SqlClient 7.0.3, la versione stabile attuale.

Prerequisiti

Ti serve l'SDK .NET 10 o un SDK .NET supportato successivamente.

Creare un database SQL

Crea o collegati a un database SQL su una delle seguenti piattaforme:

Il quickstart crea la propria tabella, quindi i dati di esempio non sono necessari. L'identità del database necessita del permesso per connettersi e creare, inserire e selezionare da una tabella.

Per il database SQL in Microsoft Fabric, copia i nomi del server e del database dall'elemento SQL database. Non usare l'endpoint di SQL analytics. L'identità richiede l'autorizzazione di lettura dell'elemento, che può essere fornita da un ruolo dell'area di lavoro o da un'autorizzazione a livello di elemento. Per ulteriori informazioni, vedi Autenticazione nel database SQL. L'autenticazione SQL non è supportata.

Per database SQL di Azure, configura l'autenticazione e l'accesso al database di Microsoft Entra ID.

Creare il progetto

Eseguire i comandi seguenti:

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

Il pacchetto di estensione fornisce modalità di autenticazione Microsoft Entra ID fornite dal driver. Un'applicazione che utilizza solo l'autenticazione integrata di Windows o l'autenticazione SQL può omettere Microsoft.Data.SqlClient.Extensions.Azure.

Configura la connessione

Imposta la SQL_CONNECTION_STRING variabile ambiente per il tuo database. Non inserire una password, un token di accesso o una stringa di connessione di produzione nel codice sorgente.

Scegli uno di questi punti di partenza e sostituisci i segnaposto.

Fabric SQL o Azure SQL con autenticazione senza password

Accedi con un'identità in Microsoft Entra ID che abbia accesso al database. Per lo sviluppo locale, usa uno strumento per sviluppatori come interfaccia della riga di comando di Azure:

az login

Copia i nomi esatti del server e del database dall'elemento SQL in Fabric o dal database Azure SQL. Per PowerShell:

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

Per Bash:

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

Per un'applicazione ospitata in Azure che si collega ad Azure SQL, concedi al database di identità gestita l'accesso al database, poi usa Authentication=Active Directory Managed Identity. Per altre opzioni di Microsoft Entra ID, vedi autenticazione Microsoft Entra ID.

SQL Server su TCP

Usa il server, la porta, il database e l'accesso dal tuo SQL Server attuale o dalla guida di configurazione che hai seguito. Il seguente esempio di autenticazione SQL è per un container di sviluppo locale. Per PowerShell:

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

Per 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 Salta la validazione dei certificati del server. Usalo solo con un'istanza di sviluppo locale che non ha un certificato affidabile. Per istanze SQL Server condivise o di produzione, installare un certificato di cui il client si fida, utilizzare il nome del server su quel certificato e rimuovere TrustServerCertificate=true.

Se l'ambiente supporta l'autenticazione integrata di Windows o Kerberos, sostituisci User ID e Password con Integrated Security=true. Per i requisiti di configurazione, vedi SQL Server autentication.

Aggiungere il codice dell'applicazione

Sostituire il contenuto di Program.cs con questo codice:

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

I tipi e le dimensioni dei parametri corrispondono alle colonne della tabella. I parametri inviano valori separatamente dal testo SQL, il che impedisce a quei valori di modificare la sintassi dei comandi e aiuta SQL Server a riutilizzare i piani di interrogazione.

await using elimina il lettore e la connessione anche quando si verifica un'eccezione. Eliminando la connessione, la connessione fisica viene restituita al pool di connessioni invece di mantenere una connessione aperta per tutta la durata dell'applicazione.

Eseguire l'applicazione

Eseguire l'applicazione:

dotnet run

L'applicazione stampa la riga che ha inserito:

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

Il valore dell'identità e il timestamp variano in base a ogni database.

Se la connessione fallisce, usa il numero di errore SQL e l'ID della connessione client dall'output dell'errore. Controlla i nomi dei server e del database, l'accesso alla rete, i permessi del database, l'impostazione dell'autenticazione e la configurazione dei certificati. Non aggiungere TrustServerCertificate=true a una connessione ad Azure SQL o di produzione come soluzione generica.

Usa il pattern in un'applicazione

Mantieni questi confini quando sposti il campione in un'API, un servizio, un'applicazione desktop o un worker in background:

  • Carica le informazioni di connessione tramite il sistema di configurazione dell'applicazione.
  • Apri una connessione per una breve unità di lavoro, quindi eliminala.
  • Passare un CancellationToken tramite le chiamate open, command e reader.
  • Imposta i timeout dei comandi in base all'operazione.
  • Usa parametri per ogni valore che proviene da fuori dall'istruzione SQL.
  • Registra SqlException.Number e ClientConnectionId senza registrare credenziali o token di accesso.
  • Aggiungi ritentativi solo per errori temporanei e solo quando è sicuro ripetere l'operazione.

Passaggi successivi