Compartilhar via


integração .NET AspirePostgreSQLEntity Framework Core

Inclui: integração de hospedagem e Client integração

PostgreSQL é um poderoso sistema de banco de dados relacional de objeto de software livre com muitos anos de desenvolvimento ativo que lhe rendeu uma forte reputação de confiabilidade, robustez de recursos e desempenho. A integração .NET AspirePostgreSQLEntity Framework Core fornece uma maneira de se conectar a bancos de dados PostgreSQL existentes ou criar novas instâncias de .NET com a imagem de contêiner docker.io/library/postgres.

Integração de hospedagem

O modelo de integração de hospedagem PostgreSQL vários recursos PostgreSQL como os seguintes tipos.

Para acessar esses tipos e APIs e expressá-los como elementos no projeto de hospedagem de aplicativo, instale o pacote NuGet :

dotnet add package Aspire.Hosting.PostgreSQL

Para obter mais informações, consulte dotnet add package ou Gerenciar dependências de pacotes em .NET aplicações.

Adicionar PostgreSQL recurso de servidor

No projeto de host do aplicativo, chame AddPostgres na instância builder para adicionar um recurso de servidor PostgreSQL e, em seguida, chame AddDatabase na instância postgres para adicionar um recurso de banco de dados, conforme mostrado no exemplo a seguir:

var builder = DistributedApplication.CreateBuilder(args);

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

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

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

Quando .NET.NET Aspire adiciona uma imagem de contêiner ao host do aplicativo, conforme mostrado no exemplo anterior com a imagem docker.io/library/postgres, ele cria uma nova instância de servidor PostgreSQL no computador local. Uma referência ao servidor e à PostgreSQL instância do banco de dados (a postgresdb variável) é usada para adicionar uma dependência ao ExampleProject.

Ao adicionar um recurso de banco de dados ao modelo de aplicativo, o banco de dados será criado se ele ainda não existir. A criação do banco de dados depende das APIs de evento do host do aplicativo, especificamente ResourceReadyEvent. Em outras palavras, quando o postgres recurso estiver pronto, o evento será gerado e o recurso de banco de dados será criado.

O recurso de servidor PostgreSQL inclui credenciais padrão, contendo um username de "postgres" e password gerados aleatoriamente usando o método CreateDefaultPasswordParameter.

O método WithReference configura uma conexão no ExampleProject denominado "messaging". Para obter mais informações, consulte ciclo de vida do recurso do contêiner.

Dica

Se você preferir se conectar a um servidor PostgreSQL existente, chame AddConnectionString em vez disso. Para obter mais informações, consulte Referenciar recursos existentes.

Adicionar o recurso PostgreSQL com scripts de banco de dados

Por padrão, quando você adiciona um PostgresDatabaseResource, ele depende do seguinte script para criar o banco de dados:

CREATE DATABASE "<QUOTED_DATABASE_NAME>"

Para alterar o script padrão, encadeia uma chamada para o WithCreationScript método no construtor de recursos do banco de dados:

var builder = DistributedApplication.CreateBuilder(args);

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

var databaseName = "app_db";
var creationScript = $$"""
    -- Create the database
    CREATE DATABASE {{databaseName}};

    """;

var db = postgres.AddDatabase(databaseName)
                 .WithCreationScript(creationScript);

builder.AddProject<Projects.ExampleProject>()
       .WithReference(db)
       .WaitFor(db);

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

O exemplo anterior cria um banco de dados chamado app_db. O script é executado quando o recurso de banco de dados é criado. O script é passado como uma cadeia de caracteres para o WithCreationScript método, que é executado no contexto do PostgreSQL recurso.

Nota

Não há suporte para a conexão a um comando de banco de dados (\c) ao usar o script de criação.

Adicionar PostgreSQL recurso pgAdmin

Ao adicionar recursos ao utilizando o método , é possível encadear chamadas para a fim de adicionar o contêiner dpage/pgadmin4. Esse contêiner é um cliente multiplataforma para bancos de dados PostgreSQL, que atende a um painel de administração baseado na Web. Considere o seguinte exemplo:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
                      .WithPgAdmin();

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

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

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

O código anterior adiciona um contêiner com base na imagem docker.io/dpage/pgadmin4. O contêiner é usado para gerenciar os recursos de servidor e banco de dados PostgreSQL. O método WithPgAdmin adiciona um contêiner que atende a um painel de administração baseado na Web para bancos de dados PostgreSQL.

Configurar a porta de host pgAdmin

Para configurar a porta de host para o contêiner pgAdmin, chame o método WithHostPort no recurso de servidor PostgreSQL. O exemplo a seguir mostra como configurar a porta host para o contêiner pgAdmin:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
                      .WithPgAdmin(pgAdmin => pgAdmin.WithHostPort(5050));

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

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

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

O código anterior adiciona e configura a porta de host para o contêiner pgAdmin. A porta do host é, de outra forma, atribuída aleatoriamente.

Adicionar PostgreSQL recurso pgWeb

Ao adicionar recursos PostgreSQL ao builder com o método AddPostgres, você pode encadear chamadas para WithPgWeb para adicionar o contêiner sosedoff/pgweb. Esse contêiner é um cliente multiplataforma para bancos de dados PostgreSQL, que atende a um painel de administração baseado na Web. Considere o seguinte exemplo:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
                      .WithPgWeb();

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

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

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

O código anterior adiciona um contêiner com base na imagem docker.io/sosedoff/pgweb. Todas as instâncias de PostgresDatabaseResource cadastradas são usadas para criar um arquivo de configuração para cada instância, e cada configuração está vinculada ao diretório de marcador do contêiner pgweb. Para obter mais informações, consulte PgWeb Docs: Server favoritos de conexão.

Configurar a porta de host pgWeb

Para configurar a porta de host para o contêiner pgWeb, chame o método WithHostPort no recurso de servidor PostgreSQL. O exemplo a seguir mostra como configurar a porta host para o contêiner pgAdmin:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
                      .WithPgWeb(pgWeb => pgWeb.WithHostPort(5050));

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

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

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

O código anterior adiciona e configura a porta de host para o contêiner pgWeb. A porta do host é, de outra forma, atribuída aleatoriamente.

Adicionar PostgreSQL recurso de servidor com volume de dados

Para adicionar um volume de dados ao recurso de servidor PostgreSQL, chame o método WithDataVolume no recurso de servidor PostgreSQL:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
                      .WithDataVolume(isReadOnly: false);

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

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

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

O volume de dados é usado para persistir os dados do servidor PostgreSQL fora do ciclo de vida de seu contêiner. O volume de dados é montado no caminho /var/lib/postgresql/data no contêiner do servidor PostgreSQL e, quando um parâmetro name não é fornecido, o nome é gerado aleatoriamente. Para obter mais informações sobre volumes de dados e detalhes sobre por que eles são preferidos em vez de montagens bind, consulte a Docker documentação: Volumes.

Adicionar recurso de servidor PostgreSQL com montagem de dados vinculada

Para adicionar uma montagem de ligação de dados ao recurso de servidor PostgreSQL, chame o método WithDataBindMount:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
                      .WithDataBindMount(
                          source: @"C:\PostgreSQL\Data",
                          isReadOnly: false);

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

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

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

Importante

As montagens de dados associadas têm funcionalidade limitada em comparação com os volumes , que oferecem melhor desempenho, portabilidade e segurança, tornando-os mais adequados para ambientes de produção. No entanto, as montagens vinculadas permitem acesso direto e modificação de arquivos no sistema host, ideal para desenvolvimento e teste no qual as alterações em tempo real são necessárias.

As montagens de vínculo de dados dependem do sistema de arquivos da máquina hospedeira para manter os dados do servidor PostgreSQL em reinicializações de contêiner. A montagem de vínculo de dados é montada no caminho C:\PostgreSQL\Data do Windows (ou /PostgreSQL/Data no Unix) na máquina host dentro do contêiner do servidor PostgreSQL. Para obter mais informações sobre bind mounts, consulte Docker docs: Bind mounts.

Adicionar recurso de servidor PostgreSQL com montagem inicial de bind.

Para adicionar um bind mount de init ao recurso de servidor PostgreSQL, chame o método WithInitBindMount.

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
                      .WithInitBindMount(@"C:\PostgreSQL\Init");

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

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

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

A bind mount init depende do sistema de arquivos da máquina host para inicializar o banco de dados do servidor com a pasta PostgreSQL dos contêineres . Essa pasta é usada para inicialização, executando scripts de shell executáveis ou arquivos de comando .sql após a criação da pasta postgres-data. A montagem de bind init é montada no caminho C:\PostgreSQL\Init no Windows (ou no caminho /PostgreSQL/Init no Unix) na máquina hospedeira dentro do contêiner do servidor PostgreSQL.

Adicionar PostgreSQL recurso de servidor com parâmetros

Quando você quiser fornecer explicitamente o nome de usuário e a senha usados pela imagem de contêiner, você pode fornecer essas credenciais como parâmetros. Considere o seguinte exemplo alternativo:

var builder = DistributedApplication.CreateBuilder(args);

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

var postgres = builder.AddPostgres("postgres", username, password);
var postgresdb = postgres.AddDatabase("postgresdb");

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

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

Para obter mais informações sobre como fornecer parâmetros, consulte Parâmetros externos.

Verificações de saúde da integração de hospedagem

A integração de hospedagem PostgreSQL adiciona automaticamente uma verificação de integridade para o recurso de servidor PostgreSQL. A verificação de integridade verifica se o servidor PostgreSQL está em execução e se uma conexão pode ser estabelecida com ele.

A integração de hospedagem depende do pacote NuGet 📦 AspNetCore.HealthChecks.Npgsql.

integração Client

Para começar a usar a integração do cliente .NET AspirePostgreSQLEntity Framework Core, instale o pacote NuGet 📦Aspire.Npgsql.EntityFrameworkCore.PostgreSQL no projeto que consome o cliente, ou seja, o projeto do aplicativo que usa o cliente PostgreSQL. A integração do cliente .NET AspirePostgreSQLEntity Framework Core registra as instâncias de subclasse desejadas de DbContext que você pode usar para interagir com PostgreSQL.

dotnet add package Aspire.Npgsql.EntityFrameworkCore.PostgreSQL

Adicionar contexto de banco de dados Npgsql

No arquivo Program.cs do seu projeto cliente-consumidor, chame o método de extensão AddNpgsqlDbContext em qualquer IHostApplicationBuilder para registrar sua subclasse DbContext para uso através do contêiner de injeção de dependência. O método usa um parâmetro de nome de conexão.

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

Dica

O parâmetro connectionName deve corresponder ao nome usado ao adicionar o recurso de servidor PostgreSQL no projeto de host do aplicativo. Para obter mais informações, consulte Adicionar recurso do servidorPostgreSQL.

Depois de adicionar YourDbContext ao builder, você pode obter a instância de YourDbContext usando a injeção de dependência. Por exemplo, para recuperar o objeto da fonte de dados de um serviço de exemplo, defina-o como um parâmetro de construtor e verifique se a classe ExampleService está registrada com o contêiner de injeção de dependência:

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

Para obter mais informações sobre injeção de dependência, consulte .NET injeção de dependência.

Enriquecer o contexto de um banco de dados utilizando Npgsql

Você pode preferir usar o método Entity Framework padrão para obter um contexto de banco de dados e adicioná-lo ao contêiner de injeção de dependência:

builder.Services.AddDbContext<YourDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("postgresdb")
        ?? throw new InvalidOperationException("Connection string 'postgresdb' not found.")));

Nota

O nome da cadeia de conexão que você passa para o método GetConnectionString deve corresponder ao nome usado ao adicionar o recurso de servidor PostgreSQL no projeto de host do aplicativo. Para obter mais informações, consulte Adicionar recurso do servidorPostgreSQL.

Você tem mais flexibilidade ao criar o contexto do banco de dados dessa maneira, por exemplo:

  • Você pode reutilizar o código de configuração existente para o contexto do banco de dados sem reescrevê-lo para .NET.NET Aspire.
  • Você pode usar Entity Framework Core interceptores para modificar operações de banco de dados.
  • Você pode optar por não usar a agregação de contexto Entity Framework Core, o que pode ter um desempenho melhor em algumas circunstâncias.

Se você usar esse método, poderá aprimorar o contexto do banco de dados com repetições de estilo .NET.NET Aspire, verificações de integridade, registro em log e recursos de telemetria chamando o método EnrichNpgsqlDbContext:

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

O parâmetro settings é uma instância da classe NpgsqlEntityFrameworkCorePostgreSQLSettings.

Configuração

A integração .NET AspirePostgreSQLEntity Framework Core fornece várias abordagens de configuração e opções para atender aos requisitos e convenções do seu projeto.

Usar uma string de conexão

Ao usar uma cadeia de conexão da seção de configuração ConnectionStrings, você fornece o nome da cadeia de conexão ao chamar o método AddNpgsqlDbContext:

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

A cadeia de conexão é recuperada da seção de configuração do ConnectionStrings:

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

O EnrichNpgsqlDbContext não usará a seção de configuração de ConnectionStrings, pois espera que um DbContext seja registrado no ponto em que é chamado.

Para obter mais informações, consulte o ConnectionString.

Usar provedores de configuração

A integração .NET AspirePostgreSQLEntity Framework Core dá suporte a Microsoft.Extensions.Configuration. Ele carrega o NpgsqlEntityFrameworkCorePostgreSQLSettings de arquivos de configuração, como appsettings.json usando a chave Aspire:Npgsql:EntityFrameworkCore:PostgreSQL. Se você tiver configurado suas configurações na seção Aspire:Npgsql:EntityFrameworkCore:PostgreSQL, poderá simplesmente chamar o método sem passar nenhum parâmetro.

O exemplo a seguir mostra um arquivo appsettings.json que configura algumas das opções disponíveis:

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

Para obter o esquema PostgreSQL de integração completa do cliente Entity Framework CoreJSON, consulte Aspire. Npgsql.EntityFrameworkCore.PostgreSQL/ConfigurationSchema.json.

Usar delegados em linha

Você também pode passar o delegado Action<NpgsqlEntityFrameworkCorePostgreSQLSettings> para configurar algumas ou todas as opções diretamente, por exemplo, para definir o ConnectionString:

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

Configurar várias classes DbContext

Se você quiser registrar mais de uma DbContext com configuração diferente, poderá usar o nome da seção de configuração $"Aspire:Npgsql:EntityFrameworkCore:PostgreSQL:{typeof(TContext).Name}". A configuração json seria semelhante a:

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

Em seguida, chamar o método AddNpgsqlDbContext com o parâmetro de tipo AnotherDbContext carregaria as configurações da seção Aspire:Npgsql:EntityFrameworkCore:PostgreSQL:AnotherDbContext.

builder.AddNpgsqlDbContext<AnotherDbContext>();

Client checagens de saúde de integração

Por padrão, .NET.NET Aspireintegrações de cliente têm verificações de integridade habilitadas para todos os serviços. Da mesma forma, muitas integrações de hospedagem .NET.NET Aspire também habilitam endpoints para verificação de saúde. Para obter mais informações, consulte:

Por padrão, as integrações de .NET AspirePostgreSQLEntity Framework Core manipulam o seguinte:

  • Adiciona o DbContextHealthCheck, que chama o método EF Core de CanConnectAsync. O nome da verificação de saúde é o nome do tipo TContext.
  • Integra-se ao endpoint HTTP /health, que especifica que todas as verificações de integridade registradas devem passar para que o aplicativo seja considerado pronto para aceitar tráfego.

Observabilidade e telemetria

.NET .NET Aspire integrações configuram automaticamente configurações de Log, Rastreamento e Métricas, que às vezes são conhecidas como os pilares da observabilidade. Para obter mais informações sobre a observabilidade e a telemetria de integração, consulte .NET.NET Aspire visão geral das integrações. Dependendo do serviço de backup, algumas integrações só podem dar suporte a alguns desses recursos. Por exemplo, algumas integrações dão suporte a registro em log e rastreamento, mas não a métricas. Os recursos de telemetria também podem ser desabilitados usando as técnicas apresentadas na seção Configuration.

Registro

A integração .NET AspirePostgreSQLEntity Framework Core usa as seguintes categorias de Log:

  • 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

Rastreamento

A integração .NET AspirePostgreSQLEntity Framework Core emitirá as seguintes atividades de rastreamento usando OpenTelemetry:

  • Npgsql

Métricas

A integração .NET AspirePostgreSQLEntity Framework Core emitirá as seguintes métricas 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

Consulte também