콘텐츠로 이동
Docs Try Aspire
Docs Try

Connect to Azure PostgreSQL with EF Core

이 콘텐츠는 아직 번역되지 않았습니다.

Azure Database for PostgreSQL logo

This page describes how C# consuming apps connect to an Azure PostgreSQL resource that’s already modeled in your AppHost using Entity Framework Core. For the AppHost API surface — adding an Azure PostgreSQL Flexible Server, databases, authentication, and more — see Azure PostgreSQL Hosting integration.

When you reference an Azure PostgreSQL resource from your AppHost, Aspire injects the connection information into the consuming app as environment variables. Your C# app can either read those environment variables directly or use the Aspire Azure PostgreSQL EF Core client integration for automatic dependency injection, health checks, and telemetry.

To get started with the Aspire Azure PostgreSQL Entity Framework Core client integration, install the 📦 Aspire.Azure.Npgsql.EntityFrameworkCore.PostgreSQL NuGet package in the client-consuming project, that is, the project for the application that uses the Azure PostgreSQL EF Core client. The Aspire Azure PostgreSQL Entity Framework Core client integration registers your desired DbContext subclass instances that you can use to interact with PostgreSQL.

.NET CLI — Add Aspire.Azure.Npgsql.EntityFrameworkCore.PostgreSQL package
dotnet add package Aspire.Azure.Npgsql.EntityFrameworkCore.PostgreSQL

Aspire exposes each property as an environment variable named [RESOURCE]_[PROPERTY]. For instance, the Uri property of a resource called postgresdb becomes POSTGRESDB_URI.

The Azure PostgreSQL Flexible Server resource exposes the following connection properties:

Property NameDescription
HostThe hostname or IP address of the Azure PostgreSQL Flexible Server
PortThe port number the PostgreSQL server is listening on
UsernameThe username for authentication. Emitted when using password authentication; may be omitted when using Microsoft Entra ID authentication.
PasswordThe password for authentication. Present only when using password authentication; not present when using Microsoft Entra ID authentication.
UriThe connection URI in postgresql:// format without embedded credentials, for example postgresql://{Host}:{Port}?sslmode=Require
JdbcConnectionStringJDBC-format connection string without embedded credentials, for example jdbc:postgresql://{Host}:{Port}?sslmode=require&authenticationPluginClassName=com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin. Credentials are provided as separate Username and Password properties when using password authentication.

The Azure PostgreSQL database resource inherits all properties from its parent AzurePostgresFlexibleServerResource and adds:

Property NameDescription
UriThe connection URI in postgresql:// format without embedded credentials, for example postgresql://{Host}:{Port}/{DatabaseName}?sslmode=Require
JdbcConnectionStringJDBC connection string including the database name without embedded credentials, for example jdbc:postgresql://{Host}:{Port}/{DatabaseName}?sslmode=require&authenticationPluginClassName=com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin. Credentials are provided as separate Username and Password properties when using password authentication.
DatabaseNameThe name of the database

The recommended approach for C# apps is the Aspire Azure PostgreSQL EF Core client integration. It registers a pooled DbContext through dependency injection and adds health checks and telemetry automatically.

Install the 📦 Aspire.Azure.Npgsql.EntityFrameworkCore.PostgreSQL NuGet package in the client-consuming project:

.NET CLI — Add Aspire.Azure.Npgsql.EntityFrameworkCore.PostgreSQL package
dotnet add package Aspire.Azure.Npgsql.EntityFrameworkCore.PostgreSQL

In Program.cs, call AddAzureNpgsqlDbContext on your IHostApplicationBuilder to register a pooled DbContext that uses Azure authentication (Microsoft Entra ID) by default:

C# — Program.cs
builder.AddAzureNpgsqlDbContext<YourDbContext>(connectionName: "postgresdb");

Resolve the DbContext through dependency injection:

C# — ExampleService.cs
public class ExampleService(YourDbContext context)
{
// Use context...
}

For more information on dependency injection, see .NET dependency injection.

To register multiple DbContext instances with different connection names, use the keyed service pattern by configuring separate named sections. See Configure multiple DbContext classes for details.

If you need more control over DbContext registration — for example, to reuse existing configuration code, use EF Core interceptors, or opt out of context pooling — register the DbContext manually and call EnrichAzureNpgsqlDbContext to add Aspire health checks, retries, logging, and telemetry:

C# — Program.cs
builder.Services.AddDbContext<YourDbContext>(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("postgresdb")
?? throw new InvalidOperationException("Connection string 'postgresdb' not found.")));
builder.EnrichAzureNpgsqlDbContext<YourDbContext>(
configureSettings: settings =>
{
settings.DisableRetry = false;
settings.CommandTimeout = 30;
});

The settings parameter is an instance of AzureNpgsqlEntityFrameworkCorePostgreSQLSettings.

The client integration supports multiple ways to provide configuration.

Connection strings. When using a connection string from the ConnectionStrings configuration section, pass the connection name to AddAzureNpgsqlDbContext:

C# — Program.cs
builder.AddAzureNpgsqlDbContext<YourDbContext>("postgresdb");

The connection string is resolved from the ConnectionStrings section:

JSON — appsettings.json
{
"ConnectionStrings": {
"postgresdb": "Host=myserver;Database=test"
}
}

The username and password are automatically inferred from the credential configured in the settings. For more information, see the Npgsql connection string documentation.

Configuration providers. The client integration supports Microsoft.Extensions.Configuration. It loads AzureNpgsqlEntityFrameworkCorePostgreSQLSettings from appsettings.json using the Aspire:Npgsql:EntityFrameworkCore:PostgreSQL key:

JSON — appsettings.json
{
"Aspire": {
"Npgsql": {
"EntityFrameworkCore": {
"PostgreSQL": {
"DisableHealthChecks": true,
"DisableTracing": true
}
}
}
}
}

Inline delegates. Pass an Action<AzureNpgsqlEntityFrameworkCorePostgreSQLSettings> to configure settings inline, for example to disable health checks:

C# — Program.cs
builder.AddAzureNpgsqlDbContext<YourDbContext>(
"postgresdb",
settings => settings.DisableHealthChecks = true);

Use the AzureNpgsqlEntityFrameworkCorePostgreSQLSettings.Credential property to establish a connection. If no credential is configured, a default Azure credential is used. When the connection string contains a username and password, the credential is ignored.

Troubleshooting. In the rare case that the Username property isn’t provided and the integration can’t detect it using the application’s Managed Identity, Npgsql throws an exception similar to:

Npgsql.PostgresException (0x80004005): 28P01: password authentication failed for user …

In this case, configure the Username property in the connection string and use EnrichAzureNpgsqlDbContext:

C# — Program.cs
builder.Services.AddDbContextPool<YourDbContext>(
options => options.UseNpgsql(connectionString));
builder.EnrichAzureNpgsqlDbContext<YourDbContext>();

To register more than one DbContext with different configuration, use the $"Aspire:Npgsql:EntityFrameworkCore:PostgreSQL:{typeof(TContext).Name}" configuration section name:

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

Call AddAzureNpgsqlDbContext with the AnotherDbContext type parameter to load settings from the Aspire:Npgsql:EntityFrameworkCore:PostgreSQL:AnotherDbContext section:

C# — Program.cs
builder.AddAzureNpgsqlDbContext<AnotherDbContext>();

Aspire client integrations enable health checks by default. The Azure PostgreSQL EF Core client integration adds:

  • The DbContextHealthCheck, which calls EF Core’s CanConnectAsync method. The name of the health check is the name of the TContext type.
  • Integration with the /health HTTP endpoint, where all registered health checks must pass before the app is considered ready to accept traffic.

The Aspire Azure PostgreSQL EF Core client integration automatically configures logging, tracing, and metrics through OpenTelemetry.

Logging categories:

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

Tracing activities:

  • Npgsql

Metrics:

  • 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

Any of these telemetry features can be disabled through the configuration options above.