# Connect to PostgreSQL with EF Core

<Image
  src={postgresIcon}
  alt="PostgreSQL logo"
  width={100}
  height={100}
  class:list={'float-inline-left icon'}
  data-zoom-off
/>

This page describes how .NET consuming apps connect to a PostgreSQL database using [Entity Framework Core](https://learn.microsoft.com/ef/core/) and the `Aspire.Npgsql.EntityFrameworkCore.PostgreSQL` client integration. For AppHost setup — adding a PostgreSQL server, databases, pgAdmin, pgWeb, volumes, and more — see [PostgreSQL Hosting integration](/integrations/databases/postgres/postgres-host/).

EF Core is a .NET-only technology. If your consuming app is written in Go, Python, TypeScript, or another language, see [Connect to PostgreSQL](/integrations/databases/postgres/postgres-connect/) for the environment variable reference and per-language examples.

## Connection properties

When you reference a PostgreSQL resource from your AppHost using `WithReference`, Aspire injects the connection information into the consuming app as environment variables. Aspire exposes each property as an environment variable named `[RESOURCE]_[PROPERTY]`. For instance, the `ConnectionString` property of a resource called `postgresdb` becomes `POSTGRESDB_CONNECTIONSTRING`.

### PostgreSQL server

| Property Name          | Environment Variable           | Description |
| ---------------------- | ------------------------------ | ----------- |
| `Host`                 | `[RESOURCE]_HOST`              | The hostname or IP address of the PostgreSQL server |
| `Port`                 | `[RESOURCE]_PORT`              | The port number the PostgreSQL server is listening on |
| `Username`             | `[RESOURCE]_USERNAME`          | The username for authentication |
| `Password`             | `[RESOURCE]_PASSWORD`          | The password for authentication |

### PostgreSQL database

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

| Property Name          | Environment Variable               | Description |
| ---------------------- | ---------------------------------- | ----------- |
| `DatabaseName`         | `[RESOURCE]_DATABASENAME`          | The name of the database |
| `JdbcConnectionString` | `[RESOURCE]_JDBCCONNECTIONSTRING`  | JDBC-format connection string |

## Connect from your app

EF Core is .NET-only. The steps below apply to any .NET consuming app that references a PostgreSQL database resource from the AppHost.

#### Install the client integration

Install the [📦 Aspire.Npgsql.EntityFrameworkCore.PostgreSQL](https://www.nuget.org/packages/Aspire.Npgsql.EntityFrameworkCore.PostgreSQL) NuGet package in the client-consuming project:

<InstallDotNetPackage packageName="Aspire.Npgsql.EntityFrameworkCore.PostgreSQL" />

#### Add the Npgsql DbContext

In _Program.cs_, call `AddNpgsqlDbContext<T>` on your `IHostApplicationBuilder` to register your `DbContext` subclass in the dependency injection container:

```csharp title="C# — Program.cs"
builder.AddNpgsqlDbContext<YourDbContext>(connectionName: "postgresdb");
```
**Tip:** The `connectionName` must match the PostgreSQL database resource name from the AppHost. For more information, see [Add PostgreSQL server resource](/integrations/databases/postgres/postgres-host/#add-postgresql-server-resource).

Resolve the `DbContext` through dependency injection:

```csharp title="C# — ExampleService.cs"
public class ExampleService(YourDbContext context)
{
    // Use context to interact with the database...
}
```

#### Add keyed DbContext instances

To register more than one `DbContext` targeting different databases, use the keyed services overload:

```csharp title="C# — Program.cs"
builder.AddNpgsqlDbContext<CatalogDbContext>(connectionName: "catalogdb");
builder.AddNpgsqlDbContext<OrdersDbContext>(connectionName: "ordersdb");
```

Then resolve each instance by key using `[FromKeyedServices]`:

```csharp title="C# — ExampleService.cs"
public class ExampleService(
    [FromKeyedServices("catalogdb")] CatalogDbContext catalogContext,
    [FromKeyedServices("ordersdb")] OrdersDbContext ordersContext)
{
    // Use each context independently...
}
```

#### Enrich an existing DbContext

If you already register your `DbContext` using the standard EF Core approach, you can enhance it with Aspire-style retries, health checks, logging, and telemetry by calling `EnrichNpgsqlDbContext`:

```csharp title="C# — Program.cs"
builder.Services.AddDbContext<YourDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("postgresdb")
        ?? throw new InvalidOperationException("Connection string 'postgresdb' not found.")));

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

#### Configuration providers

The client integration loads `NpgsqlEntityFrameworkCorePostgreSQLSettings` from configuration files such as _appsettings.json_ using the `Aspire:Npgsql:EntityFrameworkCore:PostgreSQL` key:

```json title="JSON — appsettings.json"
{
  "Aspire": {
    "Npgsql": {
      "EntityFrameworkCore": {
        "PostgreSQL": {
          "ConnectionString": "Host=myserver;Database=postgresdb",
          "DisableHealthChecks": false,
          "DisableTracing": false,
          "DisableMetrics": false
        }
      }
    }
  }
}
```

To configure multiple `DbContext` classes with separate settings, use the context type name as a sub-key:

```json title="JSON — appsettings.json"
{
  "Aspire": {
    "Npgsql": {
      "EntityFrameworkCore": {
        "PostgreSQL": {
          "ConnectionString": "<DEFAULT CONNECTION STRING>",
          "AnotherDbContext": {
            "ConnectionString": "<ANOTHER CONNECTION STRING>",
            "DisableTracing": false
          }
        }
      }
    }
  }
}
```

For the complete JSON schema, see [Aspire.Npgsql.EntityFrameworkCore.PostgreSQL/ConfigurationSchema.json](https://github.com/microsoft/aspire/blob/main/src/Components/Aspire.Npgsql.EntityFrameworkCore.PostgreSQL/ConfigurationSchema.json).

You can also pass inline configuration using an `Action<NpgsqlEntityFrameworkCorePostgreSQLSettings>` delegate:

```csharp title="C# — Program.cs"
builder.AddNpgsqlDbContext<YourDbContext>(
    "postgresdb",
    static settings => settings.DisableHealthChecks = true);
```

#### Health checks

By default, the integration registers a [`DbContextHealthCheck`](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/blob/master/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs) that calls EF Core's `CanConnectAsync` method. The health check name is the name of the `TContext` type. It integrates with the `/health` HTTP endpoint so all registered health checks must pass before the app is considered ready to accept traffic.

#### Observability and telemetry

The 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.Migrations`
- `Microsoft.EntityFrameworkCore.Infrastructure`
- `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 telemetry feature can be disabled through configuration options above.

## See also

- [Get started with the PostgreSQL EF Core integrations](/integrations/databases/efcore/postgres/postgresql-get-started/)
- [PostgreSQL Hosting integration](/integrations/databases/postgres/postgres-host/)
- [Entity Framework Core overview](https://learn.microsoft.com/ef/core/)
- [EF Core migrations](https://learn.microsoft.com/ef/core/managing-schemas/migrations/)