.NET Aspire PostgreSQL Entity Framework Core 集成

包括:托管集成Client 集成

PostgreSQL 是一个强大的开源对象关系数据库系统,经过多年的积极开发,它赢得了可靠性、功能稳定性和性能的强烈声誉。 .NET Aspire PostgreSQL Entity Framework Core 集成提供了连接到现有 PostgreSQL 数据库的方法,或者使用 .NET从 docker.io/library/postgres 创建新实例。

托管集成

PostgreSQL 托管集成模型将各种 PostgreSQL 资源建模为以下类型。

若要访问这些类型和 API,并将其作为资源表达在您的 应用主机 项目中,请安装 📦Aspire.Hosting.PostgreSQL 的 NuGet 包:

dotnet add package Aspire.Hosting.PostgreSQL

有关详细信息,请参阅 dotnet add package在 .NET 应用程序中管理软件包依赖项

添加 PostgreSQL 服务器资源

在应用主机项目中,在 AddPostgres 实例上调用 builder 以添加 PostgreSQL 服务器资源,然后在 AddDatabase 实例上调用 postgres 以添加数据库资源,如以下示例所示:

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...

当 .NET.NET Aspire 将容器映像添加到应用主机时,如上例中所示的 docker.io/library/postgres 映像,它会在本地计算机上创建新的 PostgreSQL 服务器实例。 引用你的 PostgreSQL 服务器和 PostgreSQL 数据库实例(即 postgresdb 变量)用于为 ExampleProject添加一个依赖关系。 PostgreSQL 服务器资源包含默认凭据,其中 username"postgres"password 是使用 CreateDefaultPasswordParameter 方法随机生成的。

WithReference 方法在名为 ExampleProject"messaging" 中配置连接。 有关详细信息,请参阅 容器资源生命周期

提示

如果想要连接到现有 PostgreSQL 服务器,请改为调用 AddConnectionString。 有关详细信息,请参阅 引用现有资源

添加 PostgreSQL pgAdmin 资源

使用 PostgreSQL 方法将 builder 资源添加到 AddPostgres 时,可以链接调用 WithPgAdmin 以添加 dpage/pgadmin4 容器。 此容器是用于 PostgreSQL 数据库的跨平台客户端,提供基于 Web 的管理仪表板。 请考虑以下示例:

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...

前面的代码基于 docker.io/dpage/pgadmin4 镜像添加容器。 容器用于管理 PostgreSQL 服务器和数据库资源。 WithPgAdmin 方法添加一个容器,该容器为 PostgreSQL 数据库提供基于 Web 的管理仪表板。

配置 pgAdmin 主机端口

若要配置 pgAdmin 容器的主机端口,请在 PostgreSQL 服务器资源上调用 WithHostPort 方法。 以下示例演示如何为 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...

前面的代码添加并配置 pgAdmin 容器的主机端口。 否则会随机分配主机端口。

添加 PostgreSQL pgWeb 资源

使用 PostgreSQL 方法将 builder 资源添加到 AddPostgres 时,可以链接调用 WithPgWeb 以添加 sosedoff/pgweb 容器。 此容器是用于 PostgreSQL 数据库的跨平台客户端,提供基于 Web 的管理仪表板。 请考虑以下示例:

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...

前面的代码基于 docker.io/sosedoff/pgweb 镜像添加容器。 所有已注册的 PostgresDatabaseResource 实例都用于为每个实例创建配置文件,每个配置都绑定到 pgweb 容器书签目录。 有关详细信息,请参阅 PgWeb 文档:Server 连接书签

配置 pgWeb 主机端口

若要配置 pgWeb 容器的主机端口,请在 PostgreSQL 服务器资源上调用 WithHostPort 方法。 以下示例演示如何为 pgAdmin 容器配置主机端口:

var builder = DistributedApplication.CreateBuilder(args);

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

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

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

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

前面的代码添加并配置 pgWeb 容器的主机端口。 否则会随机分配主机端口。

将服务器资源 PostgreSQL 与数据卷一起添加

若要将数据卷添加到 PostgreSQL 服务器资源,请在 WithDataVolume 服务器资源上调用 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...

数据卷用于在其容器生命周期之外保留 PostgreSQL 服务器数据。 数据卷装载在 /var/lib/postgresql/data 服务器容器中的 PostgreSQL 路径,如果未提供 name 参数,则会随机生成名称。 有关数据卷的详细信息,以及它们为何优先于 绑定装载的详细信息,请参阅 Docker 文档:卷

添加带有数据绑定挂载的 PostgreSQL 服务器资源

若要将数据绑定装载添加到 PostgreSQL 服务器资源,请调用 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...

重要

相比之下,绑定 装载的数据功能有限,而 提供了更好的性能、可移植性和安全性,使得它们更适合用于生产环境。 但是,绑定装载允许直接访问和修改主机系统上的文件,非常适合在需要实时更改的情况下进行开发和测试。

数据绑定装载依赖于主机的文件系统在容器重启时保留 PostgreSQL 服务器数据。 数据挂载点安装在主机上的 Windows C:\PostgreSQL\Data 路径(或 /PostgreSQL/Data上的 Unix 路径)的 PostgreSQL 服务器容器中。 有关数据绑定装载的详细信息,请参阅 Docker 文档:绑定装载

使用 init 绑定挂载添加 PostgreSQL 服务器资源

若要将 init 绑定挂载添加到 PostgreSQL 服务器资源,请调用 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...

init 绑定挂载依赖于主机的文件系统,通过容器中的 PostgreSQL 文件夹来初始化 服务器的数据库。 创建 postgres-data 文件夹后,此文件夹用于初始化、运行任何可执行 shell 脚本或 .sql 命令文件。 init 绑定装载在主机上的 C:\PostgreSQL\Init 服务器容器中的 Windows 的 /PostgreSQL/Init(或 Unix的 PostgreSQL)路径上进行安装。

使用参数添加 PostgreSQL 服务器资源

如果要显式提供容器映像使用的用户名和密码,可以将这些凭据作为参数提供。 请考虑以下替代示例:

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...

有关提供参数的详细信息,请参阅 外部参数

托管集成运行状况检查

托管集成的 PostgreSQL 会自动为 PostgreSQL 服务器资源添加运行状况检查。 运行状况检查验证 PostgreSQL 服务器是否正在运行,并且可以建立与服务器的连接。

托管集成依赖于 📦 AspNetCore.HealthChecks.Npgsql NuGet 包。

Client 集成

若要开始 .NET AspirePostgreSQLEntity Framework Core 客户端集成,请在客户端使用项目中安装 📦Aspire.Npgsql.EntityFrameworkCore.PostgreSQL NuGet 包,即用于使用 PostgreSQL 客户端的应用程序的项目。 .NET Aspire PostgreSQL Entity Framework Core 客户端集成注册您希望的 DbContext 子类实例,您可以使用这些实例与 PostgreSQL进行交互。

dotnet add package Aspire.Npgsql.EntityFrameworkCore.PostgreSQL

添加 Npgsql 数据库上下文

在客户端使用项目的 Program.cs 文件中,对任何 AddNpgsqlDbContext 调用 IHostApplicationBuilder 扩展方法,以注册 DbContext 子类,以便通过依赖项注入容器使用。 该方法采用连接名称参数。

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

提示

connectionName 参数必须与在应用主机项目中添加 PostgreSQL 服务器资源时使用的名称匹配。 有关详细信息,请参阅 添加 PostgreSQL 服务器资源

YourDbContext 添加到生成器后,可以使用依赖项注入获取 YourDbContext 实例。 例如,若要从示例服务中检索数据源对象,请将其定义为构造函数参数,并确保 ExampleService 类注册到依赖项注入容器:

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

有关依赖项注入的详细信息,请参阅 .NET 依赖项注入

添加增强功能的 Npgsql 数据库上下文

要通过其他服务(如自动重试、健康检查、日志记录和遥测)来增强 DbContext,请调用 EnrichNpgsqlDbContext 方法。

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

settings 参数是 NpgsqlEntityFrameworkCorePostgreSQLSettings 类的实例。

配置

.NET Aspire PostgreSQL Entity Framework Core 集成提供了多种配置方法和选项,以满足项目的要求和约定。

使用连接字符串

使用 ConnectionStrings 配置部分中的连接字符串时,在调用 AddNpgsqlDbContext 方法时提供连接字符串的名称:

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

ConnectionStrings 配置段中检索连接字符串:

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

EnrichNpgsqlDbContext 不会使用 ConnectionStrings 配置部分,因为它预期在调用前已注册 DbContext

有关详细信息,请参阅 ConnectionString

使用配置提供程序

.NET Aspire PostgreSQL Entity Framework Core 集成支持 Microsoft.Extensions.Configuration。 它使用 NpgsqlEntityFrameworkCorePostgreSQLSettings 键从配置文件(例如 appsettings.json)加载 Aspire:Npgsql:EntityFrameworkCore:PostgreSQL。 如果在 Aspire:Npgsql:EntityFrameworkCore:PostgreSQL 节中设置了配置,只需调用该方法即可不传递任何参数。

以下示例显示了一个 appsettings.json 文件,该文件配置了一些可用选项:

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

有关完整的 PostgreSQLEntity Framework Core 客户端集成 JSON 架构,请参阅 Aspire。Npgsql.EntityFrameworkCore.PostgreSQL/ConfigurationSchema.json

使用内联委托

您还可以传递 Action<NpgsqlEntityFrameworkCorePostgreSQLSettings> 委托,以便在内联中设置部分或全部选项,例如设置 ConnectionString

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

配置多个 DbContext 类

如果您想为多个 DbContext 注册不同的配置,可以使用 $"Aspire:Npgsql:EntityFrameworkCore:PostgreSQL:{typeof(TContext).Name}" 配置段名称。 json 配置如下所示:

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

然后,使用 AddNpgsqlDbContext 类型参数调用 AnotherDbContext 方法将从 Aspire:Npgsql:EntityFrameworkCore:PostgreSQL:AnotherDbContext 节加载设置。

builder.AddNpgsqlDbContext<AnotherDbContext>();

健康检查

默认情况下,.NET.NET Aspire 集成为所有服务启用 运行状况检查。 有关详细信息,请参阅 .NET.NET Aspire 集成概述

默认情况下,.NET AspirePostgreSQLEntity Framework Core 集成处理以下内容:

  • 添加 DbContextHealthCheck,并调用 EF Core的 CanConnectAsync 方法。 健康检查的名称来自于 TContext 类型的名称。
  • /health HTTP 端点集成,该端点要求所有已注册的健康检查必须通过,应用才能被视为准备好接受流量。

可观测性和遥测

.NET .NET Aspire 集成会自动设置日志记录、跟踪和指标配置,这些配置有时称为 可观测性的支柱。 有关集成可观测性和遥测的详细信息,请参阅 .NET.NET Aspire 集成概述。 根据支持服务,某些集成可能仅支持其中一些功能。 例如,某些集成支持日志记录和跟踪,但不支持指标。 也可以使用 配置 部分中介绍的技术禁用遥测功能。

伐木

.NET Aspire PostgreSQL Entity Framework Core 集成使用以下日志类别:

  • 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

追踪

.NET Aspire PostgreSQL Entity Framework Core 集成将使用 OpenTelemetry发出以下跟踪活动:

  • Npgsql

指标

.NET Aspire PostgreSQL Entity Framework Core 集成将使用 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

另请参阅