Condividi tramite


integrazione di .NET AspireAzurePostgreSQLEntity Framework Core

Include:integrazione dell'hosting e integrazione Client

Azure Database per PostgreSQL: l'Server flessibile è un servizio di database relazionale basato sul motore di database Postgres open source. Si tratta di un database come servizio completamente gestito che può gestire carichi di lavoro cruciali con prestazioni prevedibili, sicurezza, disponibilità elevata e scalabilità dinamica. L'integrazione .NET AspireAzurePostgreSQL consente di connettersi ai database di AzurePostgreSQL esistenti o di creare nuove istanze da .NET con l'immagine del contenitore docker.io/library/postgres.

Integrazione dell'hosting

Nella .NET AspireAzurePostgreSQL, l'integrazione di hosting modella un server e un database flessibile PostgreSQL come tipi AzurePostgresFlexibleServerResource e AzurePostgresFlexibleServerDatabaseResource. Gli altri tipi intrinsecamente disponibili nell'integrazione dell'hosting sono rappresentati nelle risorse seguenti:

Per accedere a questi tipi e API per utilizzarli come risorse nel progetto di host dell'app , installare il pacchetto NuGet 📦Aspire.Hosting.Azure.PostgreSQL.

dotnet add package Aspire.Hosting.Azure.PostgreSQL

Per ulteriori informazioni, consultare dotnet add package.

L'integrazione dell'hosting AzurePostgreSQL si basa sul pacchetto NuGet 📦Aspire.Hosting.PostgreSQL, esteso per supportare Azure. Tutto ciò che puoi fare con l'integrazione .NET AspirePostgreSQL e l'integrazione .NET AspirePostgreSQLEntity Framework Core, puoi farlo anche con questa integrazione.

Aggiungere risorsa del server AzurePostgreSQL

Dopo aver installato l'integrazione dell'hosting .NET AspireAzurePostgreSQL, chiamate il metodo di estensione AddAzurePostgresFlexibleServer nel progetto host dell'applicazione:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddAzurePostgresFlexibleServer("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");

var exampleProject = builder.AddProject<Projects.ExampleProject>()
                            .WithReference(postgresdb);

La chiamata precedente a AddAzurePostgresFlexibleServer configura la risorsa server PostgresSQL da distribuire come AzurePostgres flessibile Server.

Importante

Per impostazione predefinita, AddAzurePostgresFlexibleServer configura l'autenticazione Microsoft Entra ID. Ciò richiede modifiche alle applicazioni che devono connettersi a queste risorse. Per altre informazioni, vedere integrazione Client.

Mancia

Quando si chiama AddAzurePostgresFlexibleServer, chiama in modo implicito AddAzureProvisioning, che aggiunge il supporto per la generazione di risorse Azure in modo dinamico durante l'avvio dell'app. L'app deve configurare la sottoscrizione e il percorso appropriati. Per altre informazioni, vedere Provisioning locale: Configurazione.

Bicep generato per il provisioning

Se non si ha familiarità con Bicep, si tratta di un linguaggio specifico del dominio per la definizione delle risorse Azure. Con .NET.NET Aspirenon è necessario scrivere Bicep a mano, ma le API di provisioning generano Bicep automaticamente. Quando pubblichi l'app, il Bicep generato è output insieme al file manifesto. Quando si aggiunge una risorsa AzurePostgreSQL, viene generato il bicep seguente:


Attiva/Disattiva AzurePostgreSQL Bicep.

@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location

param principalId string

param principalType string

param principalName string

resource postgres_flexible 'Microsoft.DBforPostgreSQL/flexibleServers@2024-08-01' = {
  name: take('postgresflexible-${uniqueString(resourceGroup().id)}', 63)
  location: location
  properties: {
    authConfig: {
      activeDirectoryAuth: 'Enabled'
      passwordAuth: 'Disabled'
    }
    availabilityZone: '1'
    backup: {
      backupRetentionDays: 7
      geoRedundantBackup: 'Disabled'
    }
    highAvailability: {
      mode: 'Disabled'
    }
    storage: {
      storageSizeGB: 32
    }
    version: '16'
  }
  sku: {
    name: 'Standard_B1ms'
    tier: 'Burstable'
  }
  tags: {
    'aspire-resource-name': 'postgres-flexible'
  }
}

resource postgreSqlFirewallRule_AllowAllAzureIps 'Microsoft.DBforPostgreSQL/flexibleServers/firewallRules@2024-08-01' = {
  name: 'AllowAllAzureIps'
  properties: {
    endIpAddress: '0.0.0.0'
    startIpAddress: '0.0.0.0'
  }
  parent: postgres_flexible
}

resource postgres_flexible_admin 'Microsoft.DBforPostgreSQL/flexibleServers/administrators@2024-08-01' = {
  name: principalId
  properties: {
    principalName: principalName
    principalType: principalType
  }
  parent: postgres_flexible
  dependsOn: [
    postgres_flexible
    postgreSqlFirewallRule_AllowAllAzureIps
  ]
}

output connectionString string = 'Host=${postgres_flexible.properties.fullyQualifiedDomainName};Username=${principalName}'

Il bicep precedente è un modulo che effettua il provisioning di un server flessibile AzurePostgreSQL con le impostazioni predefinite seguenti:

  • authConfig: configurazione di autenticazione del server di PostgreSQL. Il valore predefinito è ActiveDirectoryAuth abilitato e PasswordAuth disabilitato.
  • availabilityZone: zona di disponibilità del server PostgreSQL. Il valore predefinito è 1.
  • backup: configurazione di backup del server di PostgreSQL. Il valore predefinito è BackupRetentionDays impostato su 7 e GeoRedundantBackup impostato su Disabled.
  • highAvailability: configurazione a disponibilità elevata del server PostgreSQL. Il valore predefinito è Disabled.
  • storage: configurazione di archiviazione del server PostgreSQL. Il valore predefinito è StorageSizeGB impostato su 32.
  • version: versione del server di PostgreSQL. Il valore predefinito è 16.
  • sku: SKU del server di PostgreSQL. Il valore predefinito è Standard_B1ms.
  • tags: tag del server di PostgreSQL. Il valore predefinito è aspire-resource-name impostato sul nome della risorsa Aspire, in questo caso postgres-flexible.

Oltre al server flessibile PostgreSQL, stabilisce anche una regola del firewall Azure per consentire l'accesso a tutti gli indirizzi IP Azure. Viene infine creato un amministratore per il server PostgreSQL e la stringa di connessione viene restituita come variabile di output. Il Bicep generato è un punto di partenza e può essere personalizzato per soddisfare i requisiti specifici.

Personalizzare l'infrastruttura di provisioning

Tutte le risorse .NET AspireAzure sono sottoclassi del tipo di AzureProvisioningResource. Questo tipo consente la personalizzazione del Bicep generato fornendo un'API Fluent per configurare le risorse Azure, usando l'API ConfigureInfrastructure<T>(IResourceBuilder<T>, Action<AzureResourceInfrastructure>). Ad esempio, è possibile configurare il kind, consistencyPolicy, locationse altro ancora. L'esempio seguente illustra come personalizzare la risorsa AzureAzure Cosmos DB:

builder.AddAzureCosmosDB("cosmos-db")
    .ConfigureInfrastructure(infra =>
    {
        var flexibleServer = infra.GetProvisionableResources()
                                  .OfType<PostgreSqlFlexibleServer>()
                                  .Single();

        flexibleServer.Sku = new PostgreSqlFlexibleServerSku
        {
            Tier = PostgreSqlFlexibleServerSkuTier.Burstable,
        };
        flexibleServer.HighAvailability = new PostgreSqlFlexibleServerHighAvailability
        {
            Mode = PostgreSqlFlexibleServerHighAvailabilityMode.ZoneRedundant,
            StandbyAvailabilityZone = "2",
        };
        flexibleServer.Tags.Add("ExampleKey", "Example value");
    });

Il codice precedente:

Sono disponibili molte altre opzioni di configurazione per personalizzare la risorsa server flessibile PostgreSQL. Per altre informazioni, vedere Azure.Provisioning.PostgreSql. Per ulteriori informazioni, consultare Azure. Personalizzazione dell'approvvigionamento.

Connettersi a un server flessibile AzurePostgreSQL esistente

Potrebbe essere disponibile un server flessibile AzurePostgreSQL esistente a cui connettersi. Anziché rappresentare una nuova risorsa server flessibile AzurePostgreSQL, è possibile aggiungere una stringa di connessione all'host dell'app. Per aggiungere una connessione a un server flessibile AzurePostgreSQL esistente, chiamare il metodo AddConnectionString:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddConnectionString("postgres");

builder.AddProject<Projects.WebApplication>("web")
       .WithReference(postgres);

// After adding all resources, run the app...

Nota

Le stringhe di connessione vengono usate per rappresentare un'ampia gamma di informazioni di connessione, tra cui connessioni di database, broker messaggi, URI endpoint e altri servizi. Nella .NET.NET Aspire denominazione, il termine "stringa di connessione" viene usato per rappresentare qualsiasi tipo di informazioni di connessione.

La stringa di connessione viene configurata nella configurazione dell'host dell'app, in genere in segreti utente, nella sezione ConnectionStrings. L'host dell'app inserisce questa stringa di connessione come variabile di ambiente in tutte le risorse dipendenti, ad esempio:

{
    "ConnectionStrings": {
        "postgres": "Server=<PostgreSQL-server-name>.postgres.database.azure.com;Database=<database-name>;Port=5432;Ssl Mode=Require;User Id=<username>;"
    }
}

La risorsa dipendente può accedere alla stringa di connessione inserita chiamando il metodo GetConnectionString e passando il nome della connessione come parametro, in questo caso "postgres". L'API GetConnectionString è abbreviata per IConfiguration.GetSection("ConnectionStrings")[name].

Eseguire la risorsa AzurePostgreSQL come contenitore

L'integrazione dell'hosting AzurePostgreSQL supporta l'esecuzione del server PostgreSQL come contenitore locale. Ciò è utile per le situazioni in cui si vuole eseguire il server PostgreSQL localmente a scopo di sviluppo e test, evitando la necessità di effettuare il provisioning di una risorsa Azure o connettersi a un server AzurePostgreSQL esistente.

Per eseguire il server PostgreSQL come contenitore, chiamare il metodo RunAsContainer:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddAzurePostgresFlexibleServer("postgres")
                      .RunAsContainer();

var postgresdb = postgres.AddDatabase("postgresdb");

var exampleProject = builder.AddProject<Projects.ExampleProject>()
                            .WithReference(postgresdb);

Il codice precedente configura una risorsa Server flessibile AzurePostgreSQL per l'esecuzione in locale in un contenitore.

Suggerimento (assuming the context is advice/hint).

Il metodo RunAsContainer è utile per lo sviluppo e il test locali. L'API espone un delegato facoltativo che consente di personalizzare la configurazione PostgresServerResource sottostante, ad esempio l'aggiunta di pgAdmin, pgWeb, l'aggiunta di un volume di dati o il montaggio dell'associazione dati e l'aggiunta di un montaggio di binding init. Per ulteriori informazioni, consultare la sezione di integrazione dell'hosting .NET AspirePostgreSQL.

Configurare il server AzurePostgreSQL per l'uso dell'autenticazione password

Per impostazione predefinita, il server AzurePostgreSQL è configurato per l'uso di autenticazione ID di Microsoft Entra. Se si vuole usare l'autenticazione password, è possibile configurare il server per l'uso dell'autenticazione della password chiamando il metodo WithPasswordAuthentication:

var builder = DistributedApplication.CreateBuilder(args);

var username = builder.AddParameter("username", secret: true);
var password = builder.AddParameter("password", secret: true);

var postgres = builder.AddAzurePostgresFlexibleServer("postgres")
                      .WithPasswordAuthentication(username, password);

var postgresdb = postgres.AddDatabase("postgresdb");

var exampleProject = builder.AddProject<Projects.ExampleProject>()
                            .WithReference(postgresdb);

Il codice precedente configura il server AzurePostgreSQL per l'uso dell'autenticazione password. I parametri username e password vengono aggiunti all'host dell'app come parametri e viene chiamato il metodo WithPasswordAuthentication per configurare il server AzurePostgreSQL per l'uso dell'autenticazione della password. Per altre informazioni, vedere Parametri esterni.

integrazione Client

Per iniziare a usare l'integrazione client .NET AspirePostgreSQLEntity Framework Core, installare il 📦Aspire.Npgsql.EntityFrameworkCore.PostgreSQL pacchetto NuGet nel progetto che utilizza il client, ovvero il progetto per l'applicazione che usa il client PostgreSQL. L'integrazione client .NET AspirePostgreSQLEntity Framework Core registra le istanze di sottoclasse DbContext desiderate che è possibile usare per interagire con PostgreSQL.

dotnet add package Aspire.Npgsql.EntityFrameworkCore.PostgreSQL

Aggiungere il contesto del database Npgsql

Nel file Program.cs del progetto che usa il client, chiama il metodo di estensione AddNpgsqlDbContext su qualsiasi IHostApplicationBuilder per registrare la sottoclasse DbContext da usare tramite il contenitore per l'inserimento delle dipendenze. Il metodo accetta un parametro del nome di connessione.

builder.AddNpgsqlDbContext<YourDbContext>(connectionName: "postgresdb");

Suggerimento

Il parametro connectionName deve corrispondere al nome usato quando si aggiunge la risorsa server PostgreSQL nel progetto host dell'app. Per altre informazioni, vedere Aggiungere PostgreSQL risorsa server.

Dopo aver aggiunto YourDbContext al generatore, è possibile ottenere l'istanza di YourDbContext utilizzando l'iniezione delle dipendenze. Ad esempio, per recuperare l'oggetto origine dati da un servizio di esempio, definirlo come parametro del costruttore e assicurarsi che la classe ExampleService sia registrata con il contenitore di inserimento delle dipendenze:

public class ExampleService(YourDbContext context)
{
    // Use context...
}

Per maggiori informazioni su inserimento delle dipendenze, vedere .NET inserimento delle dipendenze.

Aggiungere il contesto del database Npgsql con arricchimento

Per arricchire il DbContext con servizi aggiuntivi, ad esempio tentativi automatici, controlli di integrità, registrazione e telemetria, chiamare il metodo EnrichNpgsqlDbContext:

builder.EnrichNpgsqlDbContext<YourDbContext>(
    connectionName: "postgresdb",
    configureSettings: settings =>
    {
        settings.DisableRetry = false;
        settings.CommandTimeout = 30;
    });

Il parametro settings è un'istanza della classe NpgsqlEntityFrameworkCorePostgreSQLSettings.

Configurazione

L'integrazione .NET AspirePostgreSQLEntity Framework Core offre più approcci di configurazione e opzioni per soddisfare i requisiti e le convenzioni del progetto.

Usare una stringa di connessione

Quando si usa una stringa di connessione dalla sezione di configurazione ConnectionStrings, si specifica il nome della stringa di connessione quando si chiama il metodo AddNpgsqlDbContext:

builder.AddNpgsqlDbContext<MyDbContext>("pgdb");

La stringa di connessione viene recuperata dalla sezione di configurazione ConnectionStrings:

{
  "ConnectionStrings": {
    "pgdb": "Host=myserver;Database=test"
  }
}

Il EnrichNpgsqlDbContext non userà la sezione di configurazione ConnectionStrings perché prevede che un DbContext venga registrato nel momento in cui viene chiamato.

Per altre informazioni, vedere ConnectionString.

Usare i provider di configurazione

L'integrazione .NET AspirePostgreSQLEntity Framework Core supporta Microsoft.Extensions.Configuration. Carica il NpgsqlEntityFrameworkCorePostgreSQLSettings dai file di configurazione come appsettings.json utilizzando la chiave Aspire:Npgsql:EntityFrameworkCore:PostgreSQL. Se sono state configurate le configurazioni nella sezione Aspire:Npgsql:EntityFrameworkCore:PostgreSQL, è sufficiente chiamare il metodo senza passare alcun parametro.

L'esempio seguente mostra un file appsettings.json che configura alcune delle opzioni disponibili:

{
  "Aspire": {
    "Npgsql": {
      "EntityFrameworkCore": {
        "PostgreSQL": {
          "ConnectionString": "Host=myserver;Database=postgresdb",
          "DisableHealthChecks": true,
          "DisableTracing": true
        }
      }
    }
  }
}

Per lo schema completo PostgreSQLEntity Framework CoreJSON di integrazione client, vedere Aspire. Npgsql.EntityFrameworkCore.PostgreSQL/ConfigurationSchema.json.

Usare delegati inline

È anche possibile passare il delegato Action<NpgsqlEntityFrameworkCorePostgreSQLSettings> per configurare alcune o tutte le opzioni inline, ad esempio per impostare il ConnectionString:

builder.AddNpgsqlDbContext<YourDbContext>(
    "pgdb",
    static settings => settings.ConnectionString = "<YOUR CONNECTION STRING>");

Configurare più classi DbContext

Se si desidera registrare più DbContext con una configurazione diversa, è possibile usare $"Aspire:Npgsql:EntityFrameworkCore:PostgreSQL:{typeof(TContext).Name}" nome della sezione di configurazione. La configurazione json sarà simile alla seguente:

{
  "Aspire": {
    "Npgsql": {
      "EntityFrameworkCore": {
        "PostgreSQL": {
          "ConnectionString": "<YOUR CONNECTION STRING>",
          "DisableHealthChecks": true,
          "DisableTracing": true,
          "AnotherDbContext": {
            "ConnectionString": "<ANOTHER CONNECTION STRING>",
            "DisableTracing": false
          }
        }
      }
    }
  }
}

Chiamare quindi il metodo AddNpgsqlDbContext con AnotherDbContext parametro di tipo caricherà le impostazioni dalla sezione Aspire:Npgsql:EntityFrameworkCore:PostgreSQL:AnotherDbContext.

builder.AddNpgsqlDbContext<AnotherDbContext>();

Controlli di integrità

Per impostazione predefinita, le integrazioni di .NET.NET Aspire abilitano le verifiche dello stato di salute per tutti i servizi. Per altre informazioni, vedere panoramica delle integrazioni .NET.NET Aspire.

Per impostazione predefinita, le integrazioni .NET AspirePostgreSQLEntity Framework Core gestiscono le operazioni seguenti:

  • Aggiunge il DbContextHealthCheck, che chiama il metodo CanConnectAsync di EF Core. Il nome del controllo di integrità è il nome del tipo di TContext.
  • Si integra con l'endpoint HTTP /health, che specifica che tutti i controlli di integrità registrati devono essere passati affinché l'app sia considerata pronta ad accettare il traffico

Osservabilità e telemetria

.NET .NET Aspire le integrazioni configurano automaticamente le configurazioni di registrazione, tracciamento e metriche, talvolta note come i pilastri dell'osservabilità. Per altre informazioni sull'osservabilità e la telemetria dell'integrazione, vedere panoramica delle integrazioni .NET.NET Aspire. A seconda del servizio di backup, alcune integrazioni possono supportare solo alcune di queste funzionalità. Ad esempio, alcune integrazioni supportano la registrazione e la traccia, ma non le metriche. Le funzionalità di telemetria possono essere disabilitate anche usando le tecniche presentate nella sezione Configurazione.

Registrazione

L'integrazione .NET AspirePostgreSQLEntity Framework Core usa le categorie di log seguenti:

  • Microsoft.EntityFrameworkCore.ChangeTracking
  • Microsoft.EntityFrameworkCore.Database.Command
  • Microsoft.EntityFrameworkCore.Database.Connection
  • Microsoft.EntityFrameworkCore.Database.Transaction
  • Microsoft.EntityFrameworkCore.Migrations
  • Microsoft.EntityFrameworkCore.Infrastructure
  • Microsoft.EntityFrameworkCore.Migrations
  • Microsoft.EntityFrameworkCore.Model
  • Microsoft.EntityFrameworkCore.Model.Validation
  • Microsoft.EntityFrameworkCore.Query
  • Microsoft.EntityFrameworkCore.Update

Tracciamento

L'integrazione .NET AspirePostgreSQLEntity Framework Core genererà le attività di traccia seguenti usando OpenTelemetry:

  • Npgsql

Metriche

L'integrazione .NET AspirePostgreSQLEntity Framework Core genererà le metriche seguenti usando OpenTelemetry:

  • Microsoft.EntityFrameworkCore:

    • ec_Microsoft_EntityFrameworkCore_active_db_contexts
    • ec_Microsoft_EntityFrameworkCore_total_queries
    • ec_Microsoft_EntityFrameworkCore_queries_per_second
    • ec_Microsoft_EntityFrameworkCore_total_save_changes
    • ec_Microsoft_EntityFrameworkCore_save_changes_per_second
    • ec_Microsoft_EntityFrameworkCore_compiled_query_cache_hit_rate
    • ec_Microsoft_Entity_total_execution_strategy_operation_failures
    • ec_Microsoft_E_execution_strategy_operation_failures_per_second
    • ec_Microsoft_EntityFramew_total_optimistic_concurrency_failures
    • ec_Microsoft_EntityF_optimistic_concurrency_failures_per_second
  • Npgsql:

    • ec_Npgsql_bytes_written_per_second
    • ec_Npgsql_bytes_read_per_second
    • ec_Npgsql_commands_per_second
    • ec_Npgsql_total_commands
    • ec_Npgsql_current_commands
    • ec_Npgsql_failed_commands
    • ec_Npgsql_prepared_commands_ratio
    • ec_Npgsql_connection_pools
    • ec_Npgsql_multiplexing_average_commands_per_batch
    • ec_Npgsql_multiplexing_average_write_time_per_batch

Aggiungere Azure client Npgsql autenticato

Per impostazione predefinita, quando si chiama AddAzurePostgresFlexibleServer nell'integrazione di hosting PostgreSQL, è necessario il pacchetto NuGet 📦Azureper Identity per abilitare l'autenticazione.

dotnet add package Azure.Identity

La connessione PostgreSQL può essere utilizzata tramite l'integrazione del cliente e Azure.Identity:

builder.AddNpgsqlDbContext<YourDbContext>(
    "postgresdb", 
    configureDataSourceBuilder: (dataSourceBuilder) =>
{
    if (!string.IsNullOrEmpty(dataSourceBuilder.ConnectionStringBuilder.Password))
    {
        return;
    }

    dataSourceBuilder.UsePeriodicPasswordProvider(async (_, ct) =>
    {
        var credentials = new DefaultAzureCredential();
        var token = await credentials.GetTokenAsync(
            new TokenRequestContext([
                "https://ossrdbms-aad.database.windows.net/.default"
            ]), ct);

        return token.Token;
    },
    TimeSpan.FromHours(24),
    TimeSpan.FromSeconds(10));
});

Il frammento di codice precedente illustra come usare la classe DefaultAzureCredential del pacchetto di Azure.Identity per eseguire l'autenticazione con ID Microsoft Entra e recuperare un token per connettersi al database PostgreSQL. Il metodo UsePeriodicPasswordProvider viene usato per fornire il token al generatore di stringhe di connessione.

Vedere anche