将数据存储在符合 SQL 规范的数据库中
.NET Aspire 堆栈旨在提高工作效率,并帮助构建可靠、可缩放且安全的 Web 应用程序。 可以通过添加其中一个受支持的 Aspire 组件来快速存储结构化关系数据。
当前符合 SQL 规范的数据库组件包括:
- PostgreSQL 数据库
- SQL 数据库
- Oracle 数据库
- MySQL 数据库
注意
Microsoft 可能会增加对其他数据库系统的支持,第三方也可以参与进来,因此此列表可能会扩展。
在本单元中,了解其中三个组件,哪些数据库支持 Entity Framework Core,以及如何使用它们来存储和检索数据。
如何将数据库组件添加到项目
无论选择哪种数据库,向项目添加 .NET Aspire 数据库组件的方法都是相同的。
在应用托管进程项目中:
- 将 .NET Aspire 托管组件安装到应用托管进程项目。
- 在解决方案的应用托管进程中注册数据库并为其创建容器。
- 传递对项目的引用,它需要访问为托管数据库而创建的容器。
在使用数据库的项目中:
- 将带有 NuGet 包的 .NET Aspire 组件添加到需要数据访问权限的项目。 (可选)如果有 .NET Core Entity Framework (EF) 组件,则可以改为使用它。
- 在项目的 Program.cs 文件中注册 EF 的数据源或数据库上下文。
- 使用依赖项注入将数据源注入服务中。
让我们看看针对每个受支持的数据库执行这些步骤的具体步骤。
使用 .NET Aspire PostgreSQL 组件
.NET Aspire PostgreSQL 组件要求更改应用托管进程项目和使用数据库的任何微服务。
配置应用托管进程
首先,将相应的托管组件安装到应用托管进程:
dotnet add package Aspire.Hosting.PostgreSQL --prerelease
接下来,若要注册数据库并为其创建容器,请将此代码添加到应用托管进程的 Program.cs 文件:
var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");
还必须将对数据库服务的引用传递给使用该服务的任何项目:
var northernTradersCatalogAPI = builder.AddProject<Projects.NorthernTraders_CatalogAPI>()
.WithReference(postgresdb);
配置消耗项目
若要安装 .NET Aspire PostgreSQL 组件,请在 .NET Aspire 项目中使用如下命令:
dotnet add package Aspire.Npgsql --prerelease
或者,若要使用 .NET Aspire PostgreSQL Entity Framework Core 组件,请改用以下命令:
dotnet add package Aspire.Npgsql.EntityFrameworkCore.PostgreSQL --prerelease
或者,可以使用 Visual Studio 中的“添加”>“.NET Aspire 组件”快捷方式从 NuGet 包管理器安装组件:
*.AppHost 项目的 Program.cs 文件中的代码可创建数据库,并将其传递给想要使用它的项目:
var postgres = builder.AddPostgres("pg")
.AddDatabase("postgresdb");
var exampleProject = builder.AddProject<Projects.SampleProject>()
.WithReference(postgres);
某些 .NET Aspire 数据库组件还允许为数据库管理工具创建容器。 若要将 PgAdmin 添加到解决方案以管理 PostgreSQL 数据库,请使用以下代码:
var postgresdb = builder.AddPostgres("pg")
.AddDatabase("postgresdb")
.WithPgAdmin();
让 .NET Aspire 创建容器的好处是,你无需执行任何配置即可将 PgAdmin 连接到 PostgreSQL 数据库,这是自动完成的。
使用 PostgreSQL 数据库
在想要使用数据库的任何项目中,可添加数据源来表示与 PostgreSQL 的连接。 在 Program.cs 文件中,此代码将注册数据库:
builder.AddNpgsqlDataSource("postgresdb");
或者,若要使用 Entity Framework Core 组件,请注册数据库上下文:
builder.AddNpgsqlDbContext<YourDbContext>("postgresdb");
在消耗项目中注册数据库后,随时可以使用依赖项注入与数据源进行交互:
public class YourService(NpgsqlDataSource dataSource)
{
public async Task<IEnumerable<Catalog>> GetCatalog()
{
const string query = "SELECT * FROM catalog";
using var dbConnection = dataSource.OpenConnection();
var results = await dbConnection.QueryAsync<Catalog>(command);
return queryResult.ToArray();
}
}
或者,可以检索数据库上下文 YourDbContext
以与数据库交互:
public class YourService(YourDbContext context)
{
public async Task<IEnumerable<Catalog>> GetCatalog()
{
var items = await context.ObjectItems;
if (item is null)
{
return Results.NotFound();
}
else
{
return items;
}
}
}
配置 PostgreSQL 组件
.NET Aspire 堆栈会尝试减少需要执行的配置量。 使用依赖项注入和服务发现,无需在项目中配置连接字符串即可访问数据库。
使用应用托管进程项目创建数据库容器并将其作为对项目的引用进行传递,允许接收项目访问数据库位置、连接字符串和端口。 无需管理环境变量或 appsettings.json 文件。
但是,如果需要,或者需要更好地控制数据库的配置方式,那么还有更多选项。
使用连接字符串
在需要数据库的项目中,使用连接字符串连接到数据库。 当需要连接到未在应用托管进程中注册的数据库时,此方法非常有用。
builder.AddNpgsqlDataSource("NpgsqlConnectionString");
然后在配置文件中,可以添加连接字符串:
{
"ConnectionStrings": {
"NpgsqlConnectionString": "Host=myserver;Database=postgresdb;User id=myuser;Password=mypassword"
}
}
使用配置提供程序
.NET Aspire 具有一项组件功能,允许它们支持 Microsoft.Extensions.Configuration
。 PostgreSQL 组件支持此功能,默认情况下,它使用 Aspire:Npgsql
键来查找设置。 在使用 appsettings.json 的项目中,示例配置可能如下所示:
{
"Aspire": {
"Npgsql": {
"ConnectionString": "Host=myserver;Database=postgresdb;User id=myuser;Password=mypassword",
"HealthChecks": true,
"Tracing": true,
"Metrics": true
}
}
}
前面的配置是设置连接字符串,并为 PostgreSQL 组件启用运行状况检查、跟踪和指标。 然后,代码不再需要指定连接字符串,只需使用 builder.AddNpgsqlDataSource();
。
如果使用 PostgreSQL Entity Framework Core 组件,则可以使用 Aspire:Npgsql:EntityFrameworkCore:PostgreSQL
键来配置数据库上下文:
{
"Aspire": {
"Npgsql": {
"EntityFrameworkCore": {
"PostgreSQL": {
"ConnectionString": "Host=myserver;Database=postgresdb;User id=myuser;Password=mypassword",
"MaxRetryCount": 0,
"HealthChecks": false,
"Tracing": false
}
}
}
}
}
有关实体框架配置选项的详细信息,请参阅 .NET Aspire 文档。
使用内联委托
最后一个选项是将 configureSettings
内联委托传递给 AddNpgsqlDataSource
方法。 通过此委托,可以使用代码直接配置数据库组件的设置:
builder.AddNpgsqlDataSource(
"postgresdb", static settings => settings.HealthChecks = false);
使用 .NET Aspire SQL 数据库组件
对于 SQL 数据库组件,前面的模式是相同的。 可以对应用托管进程项目和使用数据库服务的微服务进行更改。
配置应用托管进程
若要安装 SQL 数据库托管组件,请使用以下命令:
dotnet add package Aspire.Hosting.SqlServer --prerelease
若要注册容器和数据库,请将此代码添加到应用托管进程的 Program.cs 文件:
var sql = builder.AddSqlServer("sql");
var sqldb = sql.AddDatabase("sqldb");
然后,将对数据库服务的引用传递给使用该服务的任何项目:
var northernTradersCatalogAPI = builder.AddProject<Projects.NorthernTraders_CatalogAPI>()
.WithReference(sqldb);
配置消耗项目
若要安装 .NET Aspire SQL 数据库组件,请在 .NET Aspire 项目中使用如下命令:
dotnet add package Aspire.Microsoft.Data.SqlClient --prerelease
或者,若要使用 .NET Aspire SqlServer Entity Framework Core 组件,请改用以下命令:
dotnet add package Aspire.Microsoft.EntityFrameworkCore.SqlServer --prerelease
还可以使用 Visual Studio 中的“添加”>“.NET Aspire 组件”快捷方式来添加这些 NuGet 包。
用于访问数据库的 *.AppHost 项目的 Program.cs 文件代码类似于 PostgreSQL 示例:
var sqlServer = builder.AddSqlServer("sql")
.AddDatabase("sqldata");
var myService = builder.AddProject<Projects.MyService>()
.WithReference(sqlServer);
使用 SQL Server 数据库
在需要 SQL 访问权限的项目的 Program.cs 文件中,此代码将注册实体框架数据库上下文:
builder.AddSqlServerDbContext<YourDbContext>("sqldata");
在消耗项目中注册数据库后,可以使用依赖项注入与数据库上下文 YourDbContext
进行交互。 此示例代码从数据库中检索天气预报,并随机选择一个返回:
app.MapGet("/weatherforecast", async (YourDbContext context) =>
{
var rng = new Random();
var forecasts = await context.Forecasts.ToListAsync();
var forecast = forecasts[rng.Next(forecasts.Count)];
return forecast;
});
配置 SQL Server 组件
与以前一样,如果在应用托管进程和消耗项目中使用相同的数据库名称,则无需配置 SQL Server 数据库与项目之间的连接。 .NET Aspire SQL Server 组件还支持通过其他方法来配置组件。
使用配置提供程序
SQL Server 组件还支持 Microsoft.Extensions.Configuration
。 默认情况下,它使用 Aspire:SqlServer:SqlClient
键来查找设置。 在使用 appsettings.json 的项目中,示例配置可能如下所示:
{
"Aspire": {
"SqlServer": {
"SqlClient": {
"ConnectionString": "YOUR_CONNECTIONSTRING",
"HealthChecks": true,
"Tracing": false,
"Metrics": false
}
}
}
}
使用内联配置
添加 SQL Server 组件时,可以将 configureSettings
内联委托传递给 AddSqlServerClient
方法。 通过此委托,可以使用代码直接配置数据库组件的设置:
builder.AddSqlServerClient("sqldata", static settings => settings.HealthChecks = false);
可以传递任何受支持的选项:
ConnectionString
:SQL Server 数据库的连接字符串HealthChecks
:用于指示是否启用数据库运行状况检查的布尔值Tracing
:用于指示是否启用 OpenTelemetry 跟踪的布尔值Metrics
:用于指示是否启用 OpenTelemetry 指标的布尔值
连接到多个数据库
SQL Server 组件通过命名实例支持多个连接。 例如,可以连接到同一项目中的两个不同的 SQL Server 数据库:
{
"Aspire": {
"SqlServer": {
"SqlClient": {
"INSTANCE_1": {
"ServiceUri": "YOUR_URI",
"HealthChecks": false
},
"INSTANCE_2": {
"ServiceUri": "YOUR_URI",
"HealthChecks": false
}
}
}
}
}
使用此配置,可以连接到同一项目中的两个不同的数据库:
builder.AddSqlServerClient("INSTANCE_1");
builder.AddSqlServerClient("INSTANCE_2");
使用 MySQL 组件
若要安装 .NET Aspire MySQL 组件,请在需要数据访问权限的 .NET Aspire 项目中使用如下命令:
dotnet add package Aspire.MySqlConnector --prerelease
或者,使用 Visual Studio 中的“添加”>“.NET Aspire 组件”快捷方式从 NuGet 包管理器安装组件。
用于访问数据库的 *.AppHost 项目的 Program.cs 文件代码类似于 PostgreSQL 示例:
var mysqldb = builder.AddMySql("mysql")
.AddDatabase("mysqldb")
.WithPhpMyAdmin();
var myService = builder.AddProject<Projects.MyService>()
.WithReference(mysqldb);
与 PostgreSQL 组件一样,MySQL 组件也允许为数据库管理工具创建容器。 前面的示例将 PhpMyAdmin 添加到解决方案。
使用 MySQL 数据库
在需要 MySQL 访问权限的项目中,该模式是相同的。 在 Program.cs 文件中,此代码将注册数据库:
builder.AddMySqlDataSource("mysqldb");
在消耗项目中注册数据库后,随时可以使用依赖项注入与数据源进行交互:
app.MapGet("/catalog", async (MySqlConnection db) =>
{
const string sql = """
SELECT Id, Name, Description, Price
FROM catalog
""";
// the db object is a connection to the MySQL database registered with AddMySqlDataSource
return await db.QueryAsync<CatalogItem>(sql);
});
配置 MySQL 组件
MySQL 组件也支持使用这三个选项来管理配置。
连接字符串
appsettings.json 文件可以包含 MySQL 数据库的连接字符串:
{
"ConnectionStrings": {
"MySqConnection": "Server=myserver;Database=mysqldb;Uid=myuser;Pwd=mypassword"
}
}
然后,在项目中,可以使用如下所示的代码通过连接字符串连接到数据库:
builder.AddMySqlDataSource("MySqConnection");
配置提供程序
Aspire:MySqlConnector
键用于配置 MySQL 组件。
{
"Aspire": {
"MySqlConnector": {
"ConnectionString": "Server=myserver;Database=mysqldb;Uid=myuser;Pwd=mypassword",
"HealthChecks": true,
"Tracing": false,
"Metrics": false
}
}
}
内联配置
builder.AddMySqlDataSource("mysqldb", static settings => settings.HealthChecks = false);
了解如何为数据库设定种子
.NET Aspire 堆栈使用容器,具有一致的环境和轻松部署的优势。 缺点是容器是无状态的。 当容器被销毁时,添加到数据库的任何数据或架构都将丢失。 .NET Aspire 提供了在创建容器时使用数据设定数据库种子的方法。
使用卷和脚本
为数据库设定种子的最简单方法是使用卷和 SQL 脚本。 卷可以一次存储多个容器的数据,提供高性能,并且易于备份或迁移。 这些卷中存储的脚本在创建容器时运行,并使用数据填充数据库。 该脚本可以是包含数据库所需的数据和架构的 SQL 文件。
例如,如果此 SQL 脚本存储在名为 postgres-backup.sql 的文件中,在 Service.API/Seed 文件夹中:
CREATE TABLE catalog (
Id INT PRIMARY KEY,
Name VARCHAR(50),
Description VARCHAR(255),
Price DECIMAL(18, 2)
);
INSERT INTO catalog (Id, Name, Description, Price)
VALUES (1, 'Item 1', 'Description of item 1', 10.99),
(2, 'Item 2', 'Description of item 2', 20.99),
(3, 'Item 3', 'Description of item 3', 30.99);
在解决方案的应用托管进程中,可以将 Service.API/Seed 文件夹绑定到容器的 /docker-entrypoint-initdb.d 文件夹。 此文件夹是 PostgreSQL 容器中的一个特殊文件夹,用于运行在创建容器时找到的任何 SQL 脚本:
var catalogDB = builder.AddPostgres("postgres")
.WithPgAdmin()
.WithEnvironment("POSTGRES_DB", "backendDB")
.WithBindMount("../Service.API/Seed", "/docker-entrypoint-initdb.d")
.AddDatabase("backendDB");
甚至可以将 SQL 脚本拆分为架构创建和数据种子设定脚本。 如果它们全部包含在 Service.API/Seed 文件夹中,则会在 .NET Aspire 创建数据库时执行它们。
使用 Entity Framework Core 为数据设定种子
对于支持 Entity Framework Core 的组件,可以使用 DbContext
类和 Entity Framework Core 迁移来为数据库设定种子。 此方法使用 C# 代码来为数据库设定种子。 但是,此种子设定只能在开发或测试期间发生,而不能在生产环境中进行。
// Register DbContext class
builder.AddNpgsqlDbContext<CatalogContext>("sqldata");
var app = builder.Build();
app.MapDefaultEndpoints();
if (app.Environment.IsDevelopment())
{
// Retrieve an instance of the DbContext class and manually run migrations during development
using (var scope = app.Services.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<CatalogContext>();
context.Database.EnsureCreated();
}
}
上述代码会检查应用环境的状态。 如果它在开发环境中,则该代码将检索 CatalogContext
类并运行 EnsureCreated
方法。 此方法可创建数据库并运行任何挂起的迁移。
有关如何为不同的数据库组件设定种子的详细信息,请参阅 .NET Aspire 文档。