Procedura per creare un database SQL di Azure nel piano gratuito e usarlo da un programma .NET che non contiene nessuna password: il programma entra con l'identità Microsoft Entra di chi lo esegue.

Occorre: un account Azure con una sottoscrizione attiva, .NET 10 sul computer, l'interfaccia a riga di comando di Azure con l'accesso già fatto (az login), un browser. Durata: circa venti minuti. Costo: il piano gratuito dà 100.000 vCore-secondi di calcolo e 32 GB di spazio al mese, per tutta la vita della sottoscrizione. Raggiunto il limite il database si mette in pausa fino al mese dopo, senza addebiti.

Il portale delle schermate è in inglese: i nomi dei comandi sono riportati come appaiono a schermo.

Creare il database

1. Apri il modulo e applica l'offerta gratuita

Nel portale, Create a resource, cerca SQL Database e premi Create. In cima alla scheda Basics c'è l'offerta gratuita: premi Apply offer e la riga diventa «Free offer applied!».

Accanto a Resource group, premi Create new e scrivi rg-guide-sql-01.

L'offerta gratuita applicata e il gruppo di risorse creato dentro il modulo

2. Dai un nome al database e crea il server

  • Database name: db-guide-01
  • Server: premi Create new

Nel modulo del server:

  • Server name: sql-guide-01
  • Location: (Europe) Italy North
  • Authentication method: Use Microsoft Entra-only authentication

L'amministratore è l'utente con cui sei entrato nel portale, e il portale lo scrive sotto. Premi OK.

Il modulo del server, con Italy North e l'accesso solo con identità Microsoft Entra

3. Controlla il piano

Con l'offerta applicata il piano lo sceglie il portale: General Purpose - Serverless, Standard-series (Gen5), 2 vCore, 32 GB di spazio.

Sotto, Behavior when free offer limit reached è su Auto-pause the database until next month: finito il credito del mese il database si ferma e non si paga niente. L'altra voce, Continue using database for additional charges, lo tiene acceso a pagamento.

Il piano scelto dall'offerta e il comportamento al raggiungimento del limite

4. Apri la rete verso il tuo computer

Premi Next: Networking. In Connectivity method scegli Public endpoint: compaiono le regole del firewall.

  • Allow Azure services and resources to access this server: lascia No
  • Add current client IP address: metti Yes

La rete pubblica e l'indirizzo del computer aggiunto al firewall

5. Controlla e crea

Premi Review + create. Il riepilogo riporta il costo stimato: 0,00 USD al mese di spazio e 0,000000 USD per vCore-secondo.

Il riepilogo prima della creazione, con il costo a zero

Premi Create. La creazione dura qualche minuto. Quando finisce, la pagina del database riporta Status Online, il piano «Free - General Purpose - Serverless: Gen5, 2 vCores» e il credito rimasto: 100.000 vCore seconds remaining.

La pagina del database appena creato

Leggere e scrivere da .NET

6. Copia la stringa di connessione

Nel menu del database, Settings > Connection strings. La prima voce, ADO.NET (Microsoft Entra passwordless authentication), è quella che serve: dentro non c'è nessuna password.

Le stringhe di connessione, con quella senza password in cima

Server=tcp:sql-guide-01.database.windows.net,1433;Initial Catalog=db-guide-01;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;Authentication="Active Directory Default";

7. Crea il progetto

dotnet new console -n sql-demo
cd sql-demo
dotnet add package Microsoft.Data.SqlClient
dotnet add package Microsoft.Data.SqlClient.Extensions.Azure

Il secondo pacchetto serve davvero: dalla versione 7 l'accesso con identità Microsoft Entra non è più dentro Microsoft.Data.SqlClient. Senza, il programma compila e poi si ferma all'apertura della connessione:

System.ArgumentException: Cannot find an authentication provider for
'ActiveDirectoryDefault'. Install the
'Microsoft.Data.SqlClient.Extensions.Azure' NuGet package to use
Active Directory (Entra ID) authentication methods.

Un terzo pacchetto chiude due avvisi:

dotnet add package System.Security.Cryptography.Pkcs --version 10.0.14

Microsoft.Data.SqlClient 7.1.1 si porta dietro System.Security.Cryptography.Pkcs 9.0.18, su cui sono aperti due avvisi di sicurezza (CVE-2026-70162 e CVE-2026-84008, entrambi di tipo «denial of service»), e la compilazione li segnala come NU1902 e NU1903. Sono chiusi nella 9.0.21 e nella 10.0.13: con il riferimento diretto alla 10.0.14 la compilazione torna pulita.

8. Scrivi il programma

Il programma crea la tabella se non c'è, la svuota, scrive tre righe e le rilegge. La stringa di connessione arriva da una variabile d'ambiente: nel codice non c'è né indirizzo né credenziale.

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

string connessione = Environment.GetEnvironmentVariable("SQL_GUIDA")!;

Stopwatch tempo = Stopwatch.StartNew();

await using SqlConnection db = new(connessione);
await db.OpenAsync();

Console.WriteLine($"Collegato in {tempo.ElapsedMilliseconds} ms a {db.Database}.\n");

await Comando(db, """
    IF OBJECT_ID('dbo.Articoli') IS NULL
        CREATE TABLE dbo.Articoli (
            Id INT IDENTITY PRIMARY KEY,
            Nome NVARCHAR(60) NOT NULL,
            Prezzo DECIMAL(8,2) NOT NULL);
    """);

await Comando(db, "TRUNCATE TABLE dbo.Articoli;");

foreach ((string nome, decimal prezzo) in new[]
{
    ("Tastiera", 49.90m),
    ("Monitor", 199.00m),
    ("Cavo di rete", 7.50m),
})
{
    await using SqlCommand inserimento = db.CreateCommand();
    inserimento.CommandText =
        "INSERT INTO dbo.Articoli (Nome, Prezzo) VALUES (@nome, @prezzo);";
    inserimento.Parameters.AddWithValue("@nome", nome);
    inserimento.Parameters.AddWithValue("@prezzo", prezzo);
    await inserimento.ExecuteNonQueryAsync();
}

await using SqlCommand lettura = db.CreateCommand();
lettura.CommandText = "SELECT Id, Nome, Prezzo FROM dbo.Articoli ORDER BY Prezzo DESC;";

await using SqlDataReader righe = await lettura.ExecuteReaderAsync();
while (await righe.ReadAsync())
{
    Console.WriteLine($"{righe.GetInt32(0)}  {righe.GetString(1),-14} {righe.GetDecimal(2),8:N2} EUR");
}

Console.WriteLine($"\nTutto in {tempo.ElapsedMilliseconds} ms.");

static async Task Comando(SqlConnection db, string sql)
{
    await using SqlCommand comando = db.CreateCommand();
    comando.CommandText = sql;
    await comando.ExecuteNonQueryAsync();
}

I valori passano come parametri, @nome e @prezzo, non concatenati nel testo della query.

9. Esegui

Metti la stringa nella variabile d'ambiente e avvia:

export SQL_GUIDA="<stringa copiata dal portale>"
dotnet run

Su Windows, in PowerShell:

$env:SQL_GUIDA = '<stringa copiata dal portale>'
dotnet run
Collegato in 3598 ms a db-guide-01.

2  Monitor          199.00 EUR
1  Tastiera          49.90 EUR
3  Cavo di rete       7.50 EUR

Tutto in 3732 ms.

Quasi tutto il tempo sta nel primo collegamento: 3598 ms per autenticarsi e aprire la connessione, 134 ms per creare la tabella, scrivere tre righe e rileggerle.

Il programma non ha mai visto una password. Authentication="Active Directory Default" fa cercare al driver un'identità già disponibile sul computer, e trova quella dell'interfaccia a riga di comando di Azure. Lo stesso programma, messo su una macchina in Azure, userebbe l'identità gestita della macchina senza cambiare una riga.

10. Controlla dal portale

Nel menu del database, Query editor, e poi il bottone Connect as con il tuo nome: anche qui non serve una password.

SELECT * FROM dbo.Articoli ORDER BY Prezzo DESC;

L'editor di query con le tre righe scritte dal programma

Le tre righe ci sono e la query ha impiegato 161 ms.

Pulire

11. Elimina il gruppo di risorse

Apri rg-guide-sql-01: contiene il database e il server.

Il gruppo di risorse con il database e il server

Premi Delete resource group. Il pannello elenca tre risorse, perché insieme al database c'è sempre il master del server. Riscrivi il nome del gruppo e premi Delete.

Il pannello di eliminazione con il nome riscritto

Conferma nella finestra che compare.

La richiesta di conferma definitiva

Eliminato il gruppo, il credito gratuito resta disponibile: il limite dell'offerta è di dieci database gratuiti per sottoscrizione.

Nomi dei comandi, schermate e tempi rilevati sul portale di Azure il 6 novembre 2026, regione Italy North, con .NET 10.0.401 e Microsoft.Data.SqlClient 7.1.1.