diff --git a/src/frontend/config/redirects.mjs b/src/frontend/config/redirects.mjs
index 4cc0fd329..68f408269 100644
--- a/src/frontend/config/redirects.mjs
+++ b/src/frontend/config/redirects.mjs
@@ -21,4 +21,6 @@ export const redirects = {
'/integrations/cloud/azure/azure-postgresql/': '/integrations/cloud/azure/azure-postgresql/azure-postgresql-get-started/',
'/integrations/databases/efcore/sql-server/': '/integrations/databases/efcore/sql-server/sql-server-get-started/',
'/integrations/databases/efcore/postgresql/': '/integrations/databases/efcore/postgres/postgresql-get-started/',
+ '/integrations/databases/efcore/azure-postgresql/': '/integrations/databases/efcore/azure-postgresql/azure-postgresql-get-started/',
+ '/integrations/databases/efcore/azure-sql/': '/integrations/databases/efcore/azure-sql/azure-sql-get-started/',
};
diff --git a/src/frontend/config/sidebar/integrations.topics.ts b/src/frontend/config/sidebar/integrations.topics.ts
index 528e7a6fa..80af1db76 100644
--- a/src/frontend/config/sidebar/integrations.topics.ts
+++ b/src/frontend/config/sidebar/integrations.topics.ts
@@ -537,11 +537,35 @@ export const integrationTopics: StarlightSidebarTopicsUserConfig = {
},
{
label: 'Azure PostgreSQL',
- slug: 'integrations/databases/efcore/azure-postgresql',
+ collapsed: true,
+ items: [
+ {
+ label: 'Get started',
+ slug: 'integrations/databases/efcore/azure-postgresql/azure-postgresql-get-started',
+ },
+ {
+ label: 'Client integration (Your app)',
+ slug: 'integrations/databases/efcore/azure-postgresql/azure-postgresql-client',
+ },
+ ],
},
{
label: 'Azure SQL',
- slug: 'integrations/databases/efcore/azure-sql',
+ collapsed: true,
+ items: [
+ {
+ label: 'Get started',
+ slug: 'integrations/databases/efcore/azure-sql/azure-sql-get-started',
+ },
+ {
+ label: 'Hosting integration (AppHost)',
+ slug: 'integrations/databases/efcore/azure-sql/azure-sql-host',
+ },
+ {
+ label: 'Client integration (Your app)',
+ slug: 'integrations/databases/efcore/azure-sql/azure-sql-client',
+ },
+ ],
},
{
label: 'MySQL Pomelo',
diff --git a/src/frontend/src/content/docs/integrations/databases/efcore/azure-postgresql.mdx b/src/frontend/src/content/docs/integrations/databases/efcore/azure-postgresql.mdx
deleted file mode 100644
index 6de833f0e..000000000
--- a/src/frontend/src/content/docs/integrations/databases/efcore/azure-postgresql.mdx
+++ /dev/null
@@ -1,489 +0,0 @@
----
-title: Azure PostgreSQL Entity Framework Core integration
-description: Learn how to use the Aspire Azure PostgreSQL Entity Framework Core integration to connect your Aspire applications to Azure PostgreSQL databases.
----
-
-import { Aside } from '@astrojs/starlight/components';
-import InstallPackage from '@components/InstallPackage.astro';
-import InstallDotNetPackage from '@components/InstallDotNetPackage.astro';
-import { Image } from 'astro:assets';
-import postgresqlIcon from '@assets/icons/azure-postgresql-icon.png';
-
-
-
-[Azure Database for PostgreSQL](https://learn.microsoft.com//azure/postgresql/)βFlexible Server is a relational database service based on the open-source Postgres database engine. It's a fully managed database-as-a-service that can handle mission-critical workloads with predictable performance, security, high availability, and dynamic scalability. The Aspire Azure PostgreSQL integration provides a way to connect to existing Azure PostgreSQL databases, or create new instances from .NET with the [`docker.io/library/postgres` container image](https://hub.docker.com/_/postgres).
-
-## Hosting integration
-
-The Aspire Azure PostgreSQL hosting integration models a PostgreSQL flexible server and database as the `AzurePostgresFlexibleServerResource` and `AzurePostgresFlexibleServerDatabaseResource` types. Other types that are inherently available in the hosting integration are represented in the following resources:
-
-- `PostgresServerResource`
-- `PostgresDatabaseResource`
-- `PgAdminContainerResource`
-- `PgWebContainerResource`
-
-To access these types and APIs for expressing them as resources in your [AppHost](/get-started/app-host/) project, install the [π¦ Aspire.Hosting.Azure.PostgreSQL](https://www.nuget.org/packages/Aspire.Hosting.Azure.PostgreSQL) NuGet package:
-
-
-
-### Add an Azure Database for PostgreSQL resource
-
-To add an Azure Database for PostgreSQL resource to your AppHost project, call the `AddAzurePostgres` method providing a name:
-
-```csharp title="C# β AppHost.cs"
-var builder = DistributedApplication.CreateBuilder(args);
-
-var postgres = builder.AddAzurePostgresFlexibleServer("postgres");
-var postgresdb = postgres.AddDatabase("postgresdb");
-
-var exampleProject = builder.AddProject()
- .WithReference(postgresdb);
-
-// After adding all resources, run the app...
-```
-
-The preceding code adds an Azure PostgreSQL resource named `postgres` with a database named `database` to the AppHost project. The `WithReference` method passes the connection information to the `ExampleProject` project.
-
-
-
-### Connect to an existing Azure PostgreSQL flexible server
-
-You might have an existing Azure Database for PostgreSQL service that you want to connect to. You can chain a call to annotate that your `AzurePostgresResource` is an existing resource:
-
-```csharp title="C# β AppHost.cs"
-var builder = DistributedApplication.CreateBuilder(args);
-
-var existingPostgresName = builder.AddParameter("existingPostgresName");
-var existingPostgresResourceGroup = builder.AddParameter("existingPostgresResourceGroup");
-
-var postgres = builder.AddAzurePostgresFlexibleServer("postgres")
- .AsExisting(existingPostgresName, existingPostgresResourceGroup);
-
-builder.AddProject()
- .WithReference(postgres);
-
-// After adding all resources, run the app...
-```
-
-For more information on treating Azure PostgreSQL resources as existing resources, see [Use existing Azure resources](/integrations/cloud/azure/overview/#use-existing-azure-resources).
-
-### Run Azure PostgreSQL resource as a container
-
-The Azure PostgreSQL hosting integration supports running the PostgreSQL server as a local container. This is beneficial for situations where you want to run the PostgreSQL server locally for development and testing purposes, avoiding the need to provision an Azure resource or connect to an existing Azure PostgreSQL server.
-
-To run the PostgreSQL server as a container, call the `RunAsContainer` method:
-
-```csharp title="C# β AppHost.cs"
-var builder = DistributedApplication.CreateBuilder(args);
-
-var postgres = builder.AddAzurePostgresFlexibleServer("postgres")
- .RunAsContainer();
-
-var postgresdb = postgres.AddDatabase("postgresdb");
-
-var exampleProject = builder.AddProject()
- .WithReference(postgresdb);
-```
-
-The preceding code configures an Azure PostgreSQL Flexible Server resource to run locally in a container.
-
-> [!TIP]
-> The `RunAsContainer` method is useful for local development and testing. The API exposes an optional delegate that enables you to customize the underlying `PostgresServerResource` configuration. For example, you can add **pgAdmin** and **pgWeb**, add a data volume or data bind mount, and add an init bind mount. For more information, see the [Aspire PostgreSQL hosting integration](/integrations/databases/postgres/postgres-host/#add-postgresql-server-resource) section.
-
-### Configure the Azure PostgreSQL server to use password authentication
-
-By default, the Azure PostgreSQL server is configured to use [Microsoft Entra ID](https://learn.microsoft.com/azure/postgresql/flexible-server/concepts-azure-ad-authentication) authentication. If you want to use password authentication, you can configure the server to use password authentication by calling the `WithPasswordAuthentication` method:
-
-```csharp title="C# β AppHost.cs"
-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()
- .WithReference(postgresdb);
-```
-
-The preceding code configures the Azure PostgreSQL server to use password authentication. The `username` and `password` parameters are added to the AppHost as parameters, and the `WithPasswordAuthentication` method is called to configure the Azure PostgreSQL server to use password authentication.
-
-### Provisioning-generated Bicep
-
-If you're new to [Bicep](https://learn.microsoft.com/azure-resource-manager/bicep/overview), it's a domain-specific language for defining Azure resources. With Aspire, you don't need to write Bicep by hand, because the provisioning APIs generate Bicep for you. When you publish your app, the generated Bicep is output alongside the manifest file. When you add an Azure PostgreSQL resource, the following Bicep is generated:
-
-```bicep title="Generated Bicep β postgres.bicep"
-@description('The location for the resource(s) to be deployed.')
-param location string = resourceGroup().location
-
-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
-}
-
-output connectionString string = 'Host=${postgres_flexible.properties.fullyQualifiedDomainName}'
-
-output name string = postgres_flexible.name
-```
-
-The preceding Bicep is a module that provisions an Azure PostgreSQL flexible server resource. Additionally, role assignments are created for the Azure resource in a separate module:
-
-```bicep title="Generated Bicep β postgres-flexible-roles.bicep"
-@description('The location for the resource(s) to be deployed.')
-param location string = resourceGroup().location
-
-param postgres_flexible_outputs_name string
-
-param principalType string
-
-param principalId string
-
-param principalName string
-
-resource postgres_flexible 'Microsoft.DBforPostgreSQL/flexibleServers@2024-08-01' existing = {
- name: postgres_flexible_outputs_name
-}
-
-resource postgres_flexible_admin 'Microsoft.DBforPostgreSQL/flexibleServers/administrators@2024-08-01' = {
- name: principalId
- properties: {
- principalName: principalName
- principalType: principalType
- }
- parent: postgres_flexible
-}
-```
-
-In addition to the PostgreSQL flexible server, it also provisions an Azure Firewall rule to allow all Azure IP addresses. Finally, an administrator is created for the PostgreSQL server, and the connection string is outputted as an output variable. The generated Bicep is a starting point and is influenced by changes to the provisioning infrastructure in C#. Customizations to the Bicep file directly will be overwritten, so make changes through the C# provisioning APIs to ensure they are reflected in the generated files.
-
-#### Customize provisioning infrastructure
-
-All Aspire Azure resources are subclasses of the `AzureProvisioningResource` type. This type enables the customization of the generated Bicep by providing a fluent API to configure the Azure resources using the `ConfigureInfrastructure` API:
-
-```csharp title="C# β AppHost.cs"
-var builder = DistributedApplication.CreateBuilder(args);
-
-builder.AddAzurePostgresFlexibleServer("postgres")
- .ConfigureInfrastructure(infra =>
- {
- var flexibleServer = infra.GetProvisionableResources()
- .OfType()
- .Single();
-
- flexibleServer.Sku = new PostgreSqlFlexibleServerSku
- {
- Tier = PostgreSqlFlexibleServerSkuTier.Burstable,
- };
- flexibleServer.HighAvailability = new PostgreSqlFlexibleServerHighAvailability
- {
- Mode = PostgreSqlFlexibleServerHighAvailabilityMode.ZoneRedundant,
- StandbyAvailabilityZone = "2",
- };
- flexibleServer.Tags.Add("ExampleKey", "Example value");
- });
-```
-
-The preceding code:
-
-- Chains a call to the `ConfigureInfrastructure` API:
- - The `infra` parameter is an instance of the `AzureResourceInfrastructure` type.
- - The provisionable resources are retrieved by calling the `GetProvisionableResources` method.
- - The single `PostgreSqlFlexibleServer` is retrieved.
- - The `sku` is set with `PostgreSqlFlexibleServerSkuTier.Burstable`.
- - The high availability properties are set with `PostgreSqlFlexibleServerHighAvailabilityMode.ZoneRedundant` in standby availability zone `"2"`.
- - A tag is added to the flexible server with a key of `ExampleKey` and a value of `Example value`.
-
-There are many more configuration options available to customize the PostgreSQL resource. For more information, see [Azure.Provisioning customization](/integrations/cloud/azure/customize-resources/#azureprovisioning-customization).
-
-## Client integration
-
-To get started with the Aspire PostgreSQL Entity Framework Core client integration, install the [π¦ Aspire.Azure.Npgsql.EntityFrameworkCore.PostgreSQL](https://www.nuget.org/packages/) NuGet package in the client-consuming project, that is, the project for the application that uses the PostgreSQL client. The Aspire PostgreSQL Entity Framework Core client integration registers your desired `DbContext` subclass instances that you can use to interact with PostgreSQL.
-
-
-
-The PostgreSQL connection can be consumed using the client integration by calling the `AddAzureNpgsqlDbContext`:
-
-```csharp title="C# β Program.cs"
-builder.AddAzureNpgsqlDbContext(
- connectionName: "postgresdb");
-```
-
-> [!TIP]
-> The `connectionName` parameter must match the name used when adding the PostgreSQL server resource in the AppHost project.
-
-The preceding code snippet demonstrates how to use the `AddAzureNpgsqlDbContext` method to register an `YourDbContext` (that's [pooled for performance](https://learn.microsoft.com/ef/core/performance/advanced-performance-topics)) instance that uses Azure authentication ([Microsoft Entra ID](https://learn.microsoft.com/azure/postgresql/flexible-server/concepts-azure-ad-authentication)). This `"postgresdb"` connection name corresponds to a connection string configuration value.
-
-After adding `YourDbContext` to the builder, you can get the `YourDbContext` instance using dependency injection. For example, to retrieve your data source object from an example service define it as a constructor parameter and ensure the `ExampleService` class is registered with the dependency injection container:
-
-```csharp
-public class ExampleService(YourDbContext context)
-{
- // Use context...
-}
-```
-
-For more information on dependency injection, see [.NET dependency injection](https://learn.microsoft.com/dotnet/core/extensions/dependency-injection).
-
-### Enrich an Npgsql database context
-
-You may prefer to use the standard Entity Framework method to obtain a database context and add it to the dependency injection container:
-
-```csharp title="C# β Program.cs"
-builder.Services.AddDbContext(options =>
- options.UseNpgsql(builder.Configuration.GetConnectionString("postgresdb")
- ?? throw new InvalidOperationException("Connection string 'postgresdb' not found.")));
-```
-
-> [!NOTE]
-> The connection string name that you pass to the `GetConnectionString` method must match the name used when adding the PostgreSQL server resource in the AppHost project. For more information, see [Add an Azure Database for PostgreSQL resource](#add-an-azure-database-for-postgresql-resource).
-
-You have more flexibility when you create the database context in this way, for example:
-
-- You can reuse existing configuration code for the database context without rewriting it for Aspire.
-- You can use Entity Framework Core interceptors to modify database operations.
-- You can choose not to use Entity Framework Core context pooling, which may perform better in some circumstances.
-
-If you use this method, you can enhance the database context with Aspire retries, health checks, logging, and telemetry features by calling the `EnrichAzureNpgsqlDbContext` method:
-
-```csharp title="C# β Program.cs"
-builder.EnrichAzureNpgsqlDbContext(
- configureSettings: settings =>
- {
- settings.DisableRetry = false;
- settings.CommandTimeout = 30;
- });
-```
-
-The `settings` parameter is an instance of the `AzureNpgsqlEntityFrameworkCorePostgreSQLSettings` class.
-
-You might also need to configure specific options of Npgsql, or register a `System.Data.Entity.DbContext` in other ways. In this case, you do so by calling the `EnrichAzureNpgsqlDbContext` extension method, as shown in the following example:
-
-```csharp title="C# β Program.cs"
-var connectionString = builder.Configuration.GetConnectionString("postgresdb");
-
-builder.Services.AddDbContextPool(
- dbContextOptionsBuilder => dbContextOptionsBuilder.UseNpgsql(connectionString));
-
-builder.EnrichAzureNpgsqlDbContext();
-```
-
-#### Configuration
-
-The Aspire Azure PostgreSQL EntityFrameworkCore Npgsql integration provides multiple options to configure the database connection based on the requirements and conventions of your project.
-
-##### Use a connection string
-
-When using a connection string defined in the `ConnectionStrings` configuration section, you provide the name of the connection string when calling `AddAzureNpgsqlDataSource`:
-
-```csharp title="C# β Program.cs"
-builder.AddAzureNpgsqlDbContext("postgresdb");
-```
-
-The connection string is retrieved from the `ConnectionStrings` configuration section, for example, consider the following JSON configuration:
-
-```json title="JSON β appsettings.json"
-{
- "ConnectionStrings": {
- "postgresdb": "Host=myserver;Database=test"
- }
-}
-```
-
-For more information on how to configure the connection string, see the [Npgsql connection string documentation](https://www.npgsql.org/doc/connection-string-parameters.html).
-
-> [!NOTE]
-> The username and password are automatically inferred from the credential provided in the settings.
-
-##### Use configuration providers
-
-The Aspire Azure PostgreSQL EntityFrameworkCore Npgsql integration supports `Microsoft.Extensions.Configuration`. It loads the `AzureNpgsqlEntityFrameworkCorePostgreSQLSettings` from configuration using the `Aspire:Npgsql:EntityFrameworkCore:PostgreSQL` key. For example, consider the following _appsettings.json_ file that configures some of the available options:
-
-```json title="JSON β appsettings.json"
-{
- "Aspire": {
- "Npgsql": {
- "EntityFrameworkCore": {
- "PostgreSQL": {
- "DisableHealthChecks": true,
- "DisableTracing": true
- }
- }
- }
- }
-}
-```
-
-##### Use inline delegates
-
-You can configure settings in code, by passing the `Action configureSettings` delegate to set up some or all the options inline, for example to disable health checks from code:
-
-```csharp title="C# β Program.cs"
-builder.AddAzureNpgsqlDbContext(
- "postgresdb",
- settings => settings.DisableHealthChecks = true);
-```
-
-Alternatively, you can use the `EnrichAzureNpgsqlDbContext` extension method to configure the settings:
-
-```csharp
-builder.EnrichAzureNpgsqlDbContext(
- settings => settings.DisableHealthChecks = true);
-```
-
-Use the `AzureNpgsqlEntityFrameworkCorePostgreSQLSettings.Credential` property to establish a connection. If no credential is configured, the `DefaultAzureCredential` 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 with a message similar to the following:
-
-> Npgsql.PostgresException (0x80004005): 28P01: password authentication failed for user ...
-
-In this case you can configure the `Username` property in the connection string and use `EnrichAzureNpgsqlDbContext`, passing the connection string in `UseNpgsql`:
-
-```csharp title="C# β Program.cs"
-builder.Services.AddDbContextPool(
- options => options.UseNpgsql(newConnectionString));
-
-builder.EnrichAzureNpgsqlDbContext();
-```
-
-#### Configure multiple DbContext classes
-
-If you want to register more than one `DbContext` with different configuration, you can use `$"Aspire:Npgsql:EntityFrameworkCore:PostgreSQL:{typeof(TContext).Name}"` configuration section name. The json configuration would look like:
-
-```json title="JSON β appsettings.json"
-{
- "Aspire": {
- "Npgsql": {
- "EntityFrameworkCore": {
- "PostgreSQL": {
- "ConnectionString": "",
- "DisableHealthChecks": true,
- "DisableTracing": true,
- "AnotherDbContext": {
- "ConnectionString": "",
- "DisableTracing": false
- }
- }
- }
- }
- }
-}
-```
-
-Then calling the `AddAzureNpgsqlDbContext` method with `AnotherDbContext` type parameter would load the settings from `Aspire:Npgsql:EntityFrameworkCore:PostgreSQL:AnotherDbContext` section.
-
-```csharp title="C# β Program.cs"
-builder.AddAzureNpgsqlDbContext();
-```
-
-By default, the Aspire PostgreSQL Entity Framework Core integrations handles the following:
-
-- Adds the [`DbContextHealthCheck`](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/blob/master/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs), which calls EF Core's `CanConnectAsync` method. The name of the health check is the name of the `TContext` type.
-- Integrates with the `/health` HTTP endpoint, which specifies all registered health checks must pass for app to be considered ready to accept traffic
-
-### Observability and telemetry
-
-Aspire integrations automatically set up Logging, Tracing, and Metrics configurations.
-
-#### Logging
-
-The Aspire PostgreSQL Entity Framework Core integration uses the following Log categories:
-
-- `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`
-
-#### Tracing
-
-The Aspire PostgreSQL Entity Framework Core integration will emit the following tracing activities using OpenTelemetry:
-
-- `Npgsql`
-
-#### Metrics
-
-The Aspire PostgreSQL Entity Framework Core integration will emit the following metrics using 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`
diff --git a/src/frontend/src/content/docs/integrations/databases/efcore/azure-postgresql/azure-postgresql-client.mdx b/src/frontend/src/content/docs/integrations/databases/efcore/azure-postgresql/azure-postgresql-client.mdx
new file mode 100644
index 000000000..2fa1a9569
--- /dev/null
+++ b/src/frontend/src/content/docs/integrations/databases/efcore/azure-postgresql/azure-postgresql-client.mdx
@@ -0,0 +1,301 @@
+---
+title: Azure PostgreSQL EF Core Client integration reference
+description: Learn how to use the Aspire Azure PostgreSQL EF Core Client integration to interact with Azure PostgreSQL databases from your Aspire projects.
+next: false
+---
+
+import { Aside } from '@astrojs/starlight/components';
+import InstallDotNetPackage from '@components/InstallDotNetPackage.astro';
+import { Image } from 'astro:assets';
+import postgresqlIcon from '@assets/icons/azure-postgresql-icon.png';
+
+
+
+To get started with the Aspire Azure PostgreSQL EF Core integrations, follow the [Get started with Azure PostgreSQL integrations](/integrations/databases/efcore/azure-postgresql/azure-postgresql-get-started/) guide.
+
+This article includes full details about the Aspire Azure PostgreSQL EF Core Client integration, which allows you to connect to and interact with Azure PostgreSQL databases from your Aspire consuming projects using Entity Framework Core.
+
+## Installation
+
+To get started with the Aspire Azure PostgreSQL Entity Framework Core client integration, install the [π¦ Aspire.Azure.Npgsql.EntityFrameworkCore.PostgreSQL](https://www.nuget.org/packages/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.
+
+
+
+## Add Azure Npgsql database context
+
+The Azure PostgreSQL connection can be consumed using the EF Core client integration by calling the `AddAzureNpgsqlDbContext`:
+
+```csharp title="C# β Program.cs"
+builder.AddAzureNpgsqlDbContext(
+ connectionName: "postgresdb");
+```
+
+
+
+> [!TIP]
+> The `connectionName` parameter must match the name used when adding the PostgreSQL server resource in the AppHost project.
+
+The preceding code snippet demonstrates how to use the `AddAzureNpgsqlDbContext` method to register a `YourDbContext` (that's [pooled for performance](https://learn.microsoft.com/ef/core/performance/advanced-performance-topics)) instance that uses Azure authentication ([Microsoft Entra ID](https://learn.microsoft.com/azure/postgresql/flexible-server/concepts-azure-ad-authentication)). This `"postgresdb"` connection name corresponds to a connection string configuration value.
+
+After adding `YourDbContext` to the builder, you can get the `YourDbContext` instance using dependency injection. For example, to retrieve your data source object from an example service define it as a constructor parameter and ensure the `ExampleService` class is registered with the dependency injection container:
+
+```csharp
+public class ExampleService(YourDbContext context)
+{
+ // Use context...
+}
+```
+
+For more information on dependency injection, see [.NET dependency injection](https://learn.microsoft.com/dotnet/core/extensions/dependency-injection).
+
+## Properties of the Azure PostgreSQL resources
+
+When you use the `WithReference` method to pass an Azure PostgreSQL flexible server or database resource from the AppHost project to a consuming client project, several properties are available to use in the consuming project.
+
+Aspire exposes each property as an environment variable named `[RESOURCE]_[PROPERTY]`. For instance, the `Uri` property of a resource called `postgresdb` becomes `POSTGRESDB_URI`.
+
+### Azure PostgreSQL flexible server resource
+
+The Azure PostgreSQL flexible server resource exposes the following connection properties:
+
+| Property Name | Description |
+| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `Host` | The hostname or IP address of the Azure PostgreSQL flexible server |
+| `Port` | The port number the PostgreSQL server is listening on |
+| `Username` | The username for authentication. This property is emitted when the server is configured for password authentication and may be omitted when using the default Microsoft Entra ID authentication. |
+| `Password` | The password for authentication. This property is emitted only when using password authentication and is not present when using Microsoft Entra ID authentication. |
+| `Uri` | The connection URI in postgresql:// format that does not embed credentials, for example `postgresql://{Host}:{Port}?sslmode=Require` |
+| `JdbcConnectionString` | JDBC-format connection string without embedded credentials, for example `jdbc:postgresql://{Host}:{Port}?sslmode=require&authenticationPluginClassName=com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin`. User and password credentials are provided as separate `Username` and `Password` properties when using password authentication. |
+
+### Azure PostgreSQL database resource
+
+The Azure PostgreSQL database resource inherits all properties from its parent `AzurePostgresFlexibleServerResource` and adds:
+
+| Property Name | Description |
+| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `Uri` | The connection URI in postgresql:// format that does not embed credentials, for example `postgresql://{Host}:{Port}/{DatabaseName}?sslmode=Require`. Credentials are exposed via other properties. |
+| `JdbcConnectionString` | JDBC 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`. User and password credentials are provided as separate `Username` and `Password` properties when using password authentication. |
+| `DatabaseName` | The name of the database |
+
+## Enrich an Npgsql database context
+
+You may prefer to use the standard Entity Framework method to obtain a database context and add it to the dependency injection container:
+
+```csharp title="C# β Program.cs"
+builder.Services.AddDbContext(options =>
+ options.UseNpgsql(builder.Configuration.GetConnectionString("postgresdb")
+ ?? throw new InvalidOperationException("Connection string 'postgresdb' not found.")));
+```
+
+> [!NOTE]
+> The connection string name that you pass to the `GetConnectionString` method must match the name used when adding the PostgreSQL server resource in the AppHost project. For more information, see [Add an Azure Database for PostgreSQL resource](/integrations/cloud/azure/azure-postgresql/azure-postgresql-host/#add-an-azure-database-for-postgresql-resource).
+
+You have more flexibility when you create the database context in this way, for example:
+
+- You can reuse existing configuration code for the database context without rewriting it for Aspire.
+- You can use Entity Framework Core interceptors to modify database operations.
+- You can choose not to use Entity Framework Core context pooling, which may perform better in some circumstances.
+
+If you use this method, you can enhance the database context with Aspire retries, health checks, logging, and telemetry features by calling the `EnrichAzureNpgsqlDbContext` method:
+
+```csharp title="C# β Program.cs"
+builder.EnrichAzureNpgsqlDbContext(
+ configureSettings: settings =>
+ {
+ settings.DisableRetry = false;
+ settings.CommandTimeout = 30;
+ });
+```
+
+The `settings` parameter is an instance of the `AzureNpgsqlEntityFrameworkCorePostgreSQLSettings` class.
+
+You might also need to configure specific options of Npgsql, or register a `System.Data.Entity.DbContext` in other ways. In this case, you do so by calling the `EnrichAzureNpgsqlDbContext` extension method, as shown in the following example:
+
+```csharp title="C# β Program.cs"
+var connectionString = builder.Configuration.GetConnectionString("postgresdb");
+
+builder.Services.AddDbContextPool(
+ dbContextOptionsBuilder => dbContextOptionsBuilder.UseNpgsql(connectionString));
+
+builder.EnrichAzureNpgsqlDbContext();
+```
+
+## Configuration
+
+The Aspire Azure PostgreSQL EntityFrameworkCore Npgsql integration provides multiple options to configure the database connection based on the requirements and conventions of your project.
+
+### Use a connection string
+
+When using a connection string defined in the `ConnectionStrings` configuration section, you provide the name of the connection string when calling `AddAzureNpgsqlDataSource`:
+
+```csharp title="C# β Program.cs"
+builder.AddAzureNpgsqlDbContext("postgresdb");
+```
+
+The connection string is retrieved from the `ConnectionStrings` configuration section, for example, consider the following JSON configuration:
+
+```json title="JSON β appsettings.json"
+{
+ "ConnectionStrings": {
+ "postgresdb": "Host=myserver;Database=test"
+ }
+}
+```
+
+For more information on how to configure the connection string, see the [Npgsql connection string documentation](https://www.npgsql.org/doc/connection-string-parameters.html).
+
+> [!NOTE]
+> The username and password are automatically inferred from the credential provided in the settings.
+
+### Use configuration providers
+
+The Aspire Azure PostgreSQL EntityFrameworkCore Npgsql integration supports `Microsoft.Extensions.Configuration`. It loads the `AzureNpgsqlEntityFrameworkCorePostgreSQLSettings` from configuration using the `Aspire:Npgsql:EntityFrameworkCore:PostgreSQL` key. For example, consider the following _appsettings.json_ file that configures some of the available options:
+
+```json title="JSON β appsettings.json"
+{
+ "Aspire": {
+ "Npgsql": {
+ "EntityFrameworkCore": {
+ "PostgreSQL": {
+ "DisableHealthChecks": true,
+ "DisableTracing": true
+ }
+ }
+ }
+ }
+}
+```
+
+### Use inline delegates
+
+You can configure settings in code, by passing the `Action configureSettings` delegate to set up some or all the options inline, for example to disable health checks from code:
+
+```csharp title="C# β Program.cs"
+builder.AddAzureNpgsqlDbContext(
+ "postgresdb",
+ settings => settings.DisableHealthChecks = true);
+```
+
+Alternatively, you can use the `EnrichAzureNpgsqlDbContext` extension method to configure the settings:
+
+```csharp
+builder.EnrichAzureNpgsqlDbContext(
+ settings => settings.DisableHealthChecks = true);
+```
+
+Use the `AzureNpgsqlEntityFrameworkCorePostgreSQLSettings.Credential` property to establish a connection. If no credential is configured, the `DefaultAzureCredential` 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 with a message similar to the following:
+
+> Npgsql.PostgresException (0x80004005): 28P01: password authentication failed for user ...
+
+In this case you can configure the `Username` property in the connection string and use `EnrichAzureNpgsqlDbContext`, passing the connection string in `UseNpgsql`:
+
+```csharp title="C# β Program.cs"
+builder.Services.AddDbContextPool(
+ options => options.UseNpgsql(newConnectionString));
+
+builder.EnrichAzureNpgsqlDbContext();
+```
+
+## Configure multiple DbContext classes
+
+If you want to register more than one `DbContext` with different configuration, you can use `$"Aspire:Npgsql:EntityFrameworkCore:PostgreSQL:{typeof(TContext).Name}"` configuration section name. The json configuration would look like:
+
+```json title="JSON β appsettings.json"
+{
+ "Aspire": {
+ "Npgsql": {
+ "EntityFrameworkCore": {
+ "PostgreSQL": {
+ "ConnectionString": "",
+ "DisableHealthChecks": true,
+ "DisableTracing": true,
+ "AnotherDbContext": {
+ "ConnectionString": "",
+ "DisableTracing": false
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+Then calling the `AddAzureNpgsqlDbContext` method with `AnotherDbContext` type parameter would load the settings from `Aspire:Npgsql:EntityFrameworkCore:PostgreSQL:AnotherDbContext` section.
+
+```csharp title="C# β Program.cs"
+builder.AddAzureNpgsqlDbContext();
+```
+
+By default, the Aspire PostgreSQL Entity Framework Core integrations handles the following:
+
+- Adds the [`DbContextHealthCheck`](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/blob/master/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs), which calls EF Core's `CanConnectAsync` method. The name of the health check is the name of the `TContext` type.
+- Integrates with the `/health` HTTP endpoint, which specifies all registered health checks must pass for app to be considered ready to accept traffic
+
+## Observability and telemetry
+
+Aspire integrations automatically set up Logging, Tracing, and Metrics configurations.
+
+### Logging
+
+The Aspire PostgreSQL Entity Framework Core integration uses the following Log categories:
+
+- `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`
+
+### Tracing
+
+The Aspire PostgreSQL Entity Framework Core integration will emit the following tracing activities using OpenTelemetry:
+
+- `Npgsql`
+
+### Metrics
+
+The Aspire PostgreSQL Entity Framework Core integration will emit the following metrics using 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`
diff --git a/src/frontend/src/content/docs/integrations/databases/efcore/azure-postgresql/azure-postgresql-get-started.mdx b/src/frontend/src/content/docs/integrations/databases/efcore/azure-postgresql/azure-postgresql-get-started.mdx
new file mode 100644
index 000000000..bc07a5843
--- /dev/null
+++ b/src/frontend/src/content/docs/integrations/databases/efcore/azure-postgresql/azure-postgresql-get-started.mdx
@@ -0,0 +1,129 @@
+---
+title: Get started with the Azure PostgreSQL EF Core integrations
+description: Learn how to set up the Aspire Azure PostgreSQL Hosting and EF Core Client integrations simply.
+prev: false
+---
+
+import { Image } from 'astro:assets';
+import { Kbd } from 'starlight-kbd/components';
+import InstallPackage from '@components/InstallPackage.astro';
+import InstallDotNetPackage from '@components/InstallDotNetPackage.astro';
+import { Aside, CardGrid, LinkCard, Code, Steps, Tabs, TabItem } from '@astrojs/starlight/components';
+import ThemeImage from '@components/ThemeImage.astro';
+import postgresqlIcon from '@assets/icons/azure-postgresql-icon.png';
+
+
+
+[Azure Database for PostgreSQL](https://learn.microsoft.com/azure/postgresql/) Flexible Server is a relational database service based on the open-source Postgres database engine. It's a fully managed database-as-a-service that can handle mission-critical workloads with predictable performance, security, high availability, and dynamic scalability. The Aspire Azure PostgreSQL integration provides a way to connect to existing Azure PostgreSQL databases, or create new instances from .NET with the [`docker.io/library/postgres` container image](https://hub.docker.com/_/postgres). This client integration uses Entity Framework Core (EF Core) to provide a robust, type-safe way to interact with your Azure PostgreSQL databases using .NET objects.
+
+In this introduction, you'll see how to install and use the Aspire Azure PostgreSQL integrations in a simple configuration. If you already have this knowledge, see [Azure PostgreSQL Hosting integration](/integrations/cloud/azure/azure-postgresql/azure-postgresql-host/) for full reference details.
+
+
+
+## Set up hosting integration
+
+To begin, install the Aspire Azure PostgreSQL Hosting integration in your Aspire AppHost project. This integration allows you to create and manage Azure PostgreSQL flexible server instances from your Aspire hosting projects:
+
+
+
+Next, in the AppHost project, create instances of Azure PostgreSQL flexible server and database resources, then pass the database to the consuming client projects:
+
+```csharp title="C# β AppHost.cs"
+var builder = DistributedApplication.CreateBuilder(args);
+
+var postgres = builder.AddAzurePostgresFlexibleServer("postgres");
+var postgresdb = postgres.AddDatabase("postgresdb");
+
+var exampleProject = builder.AddProject("apiservice")
+ .WaitFor(postgresdb)
+ .WithReference(postgresdb);
+```
+
+
+
+
+
+## Use the integration in client projects
+
+Now that the hosting integration is ready, the next step is to install and configure the client integration in any projects that need to use it.
+
+### Set up client projects
+
+In each of these consuming client projects, install the Aspire Azure PostgreSQL Entity Framework Core client integration:
+
+
+
+In the `Program.cs` file of your client-consuming project, call the `AddAzureNpgsqlDbContext` extension method on any `IHostApplicationBuilder` to register a `DbContext` for use via the dependency injection container. The method takes a connection name parameter.
+
+```csharp title="C# β Program.cs"
+builder.AddAzureNpgsqlDbContext(connectionName: "postgresdb");
+```
+
+
+
+### Use injected Azure PostgreSQL properties
+
+In the AppHost, when you used the `WithReference` method to pass an Azure PostgreSQL database resource to a consuming client project, Aspire injects several configuration properties that you can use in the consuming project.
+
+Aspire exposes each property as an environment variable named `[RESOURCE]_[PROPERTY]`. For instance, the `Uri` property of a resource called `postgresdb` becomes `POSTGRESDB_URI`.
+
+Use the `GetValue()` method to obtain these environment variables in consuming projects:
+
+```csharp title="C# - Obtain configuration properties"
+string postgresHost = builder.Configuration.GetValue("POSTGRESDB_HOST");
+string postgresPort = builder.Configuration.GetValue("POSTGRESDB_PORT");
+string postgresJDBCConnectionString = builder.Configuration.GetValue("POSTGRESDB_JDBCCONNECTIONSTRING");
+```
+
+
+
+### Use Azure PostgreSQL resources in client code
+
+Now that you've added `DbContext` to the builder in the consuming project, you can use the Azure PostgreSQL database to get and store data. Get the `DbContext` instance using dependency injection. For example, to retrieve your context object from an example service define it as a constructor parameter and ensure the `ExampleService` class is registered with the dependency injection container:
+
+```csharp title="C# β ExampleService.cs"
+public class ExampleService(ExampleDbContext context)
+{
+ // Use database context...
+}
+```
+
+Having obtained the context, you can work with the Azure PostgreSQL database using Entity Framework Core as you would in any other C# application.
+
+## Next steps
+
+Now that you have an Aspire app with Azure PostgreSQL integrations up and running, you can use the following reference documents to learn how to configure and interact with the Azure PostgreSQL resources:
+
+
+
+
+
diff --git a/src/frontend/src/content/docs/integrations/databases/efcore/azure-sql.mdx b/src/frontend/src/content/docs/integrations/databases/efcore/azure-sql/azure-sql-client.mdx
similarity index 62%
rename from src/frontend/src/content/docs/integrations/databases/efcore/azure-sql.mdx
rename to src/frontend/src/content/docs/integrations/databases/efcore/azure-sql/azure-sql-client.mdx
index 74a227618..c09cca484 100644
--- a/src/frontend/src/content/docs/integrations/databases/efcore/azure-sql.mdx
+++ b/src/frontend/src/content/docs/integrations/databases/efcore/azure-sql/azure-sql-client.mdx
@@ -1,10 +1,10 @@
---
-title: Azure SQL Entity Framework Core integration
-description: Learn how to use the Aspire Azure SQL Entity Framework Core integration to connect your Aspire applications to Azure SQL databases.
+title: Azure SQL EF Core Client integration reference
+description: Learn how to use the Aspire Azure SQL EF Core Client integration to interact with Azure SQL databases from your Aspire projects.
+next: false
---
import { Aside } from '@astrojs/starlight/components';
-import InstallPackage from '@components/InstallPackage.astro';
import InstallDotNetPackage from '@components/InstallDotNetPackage.astro';
import { Image } from 'astro:assets';
import sqlServerIcon from '@assets/icons/azure-sqlserver-icon.png';
@@ -18,113 +18,87 @@ import sqlServerIcon from '@assets/icons/azure-sqlserver-icon.png';
data-zoom-off
/>
-[Azure SQL](https://azure.microsoft.com/products/azure-sql) is a family of relational database management systems that run in the Azure cloud. The database systems are Platform-as-a-Service (PaaS) products that enable database administrators to implement highly scalable and available databases without maintaining complex infrastructures themselves. The Aspire Azure SQL Server Hosting integration provides methods to create a new Azure Database server and databases from code in your Aspire AppHost project. In a consuming project, you can use the Aspire SQL Server client integration as you would for any other SQL Server instance.
+To get started with the Aspire Azure SQL EF Core integrations, follow the [Get started with Azure SQL integrations](/integrations/databases/efcore/azure-sql/azure-sql-get-started/) guide.
-## Hosting integration
+This article includes full details about the Aspire Azure SQL EF Core Client integration, which allows you to connect to and interact with Azure SQL databases from your Aspire consuming projects using Entity Framework Core.
-The Aspire Azure SQL Database hosting integration models the SQL Server as the `AzureSqlServerResource` type and SQL databases as the `AzureSqlDatabaseResource` type. To access these types and APIs for expressing them within your AppHost project, install the [π¦ Aspire.Hosting.Azure.Sql](https://www.nuget.org/packages/Aspire.Hosting.Azure.Sql) NuGet package:
+## Installation
-
+To get started with the Aspire Azure SQL Server Entity Framework Core client integration, install the [π¦ Aspire.Microsoft.EntityFrameworkCore.SqlServer](https://www.nuget.org/packages/Aspire.Microsoft.EntityFrameworkCore.SqlServer) NuGet package in the client-consuming project, that is, the project for the application that uses the Azure SQL Server EF Core client.
-### Add Azure SQL server resource and database resource
-
-In your AppHost project, call `AddAzureSqlServer` to add and return an Azure SQL server resource builder. Chain a call to the returned resource builder to `AddDatabase`, to add an Azure SQL database resource:
+
-```csharp title="C# β AppHost.cs"
-var builder = DistributedApplication.CreateBuilder(args);
+## Add SQL Server database context
-var azureSql = builder.AddAzureSqlServer("azuresql")
- .AddDatabase("database");
+In the `Program.cs` file of your client-consuming project, call the `AddSqlServerDbContext` extension method on any `IHostApplicationBuilder` to register a `Microsoft.EntityFrameworkCore.DbContext` for use via the dependency injection container. The method takes a connection name parameter.
-var myService = builder.AddProject()
- .WithReference(azureSql);
+```csharp title="C# β Program.cs"
+builder.AddSqlServerDbContext(
+ connectionName: "database");
```
-The preceding call to `AddAzureSqlServer` configures the Azure SQL server resource to be deployed as an [Azure SQL Database server](https://learn.microsoft.com/azure/azure-sql/database/sql-database-paas-overview).
-
-