包含: -
Client 集成
SQL Server 是由Microsoft开发的关系数据库管理系统。
Aspire
SQL Server 集成使你能够连接到现有 SQL Server 实例,或使用 .NET从 mcr.microsoft.com/mssql/server 创建新实例。
托管集成
托管集成 SQL Server 将服务器建模为 SqlServerServerResource 类型和数据库作为 SqlServerDatabaseResource 类型。 若要访问这些类型和 API,请添加 .📦AspireAppHost 项目中的 Hosting.SqlServer NuGet 包。
dotnet add package Aspire.Hosting.SqlServer
有关详细信息,请参阅 dotnet 添加包 或 管理 .NET 应用程序中的包依赖性。
添加 SQL Server 资源和数据库资源
在 AppHost 项目中,调用 AddSqlServer 添加并返回 SQL Server 资源生成器。 将对返回资源生成器的调用链接到 AddDatabase,以便添加 SQL Server 数据库资源。
var builder = DistributedApplication.CreateBuilder(args);
var sql = builder.AddSqlServer("sql")
.WithLifetime(ContainerLifetime.Persistent);
var db = sql.AddDatabase("database");
builder.AddProject<Projects.ExampleProject>("exampleproject")
.WithReference(db)
.WaitFor(db);
// After adding all resources, run the app...
builder.Build().Run();
注意
SQL Server 容器启动速度较慢,因此最好使用 持久化 生命周期以避免不必要的重启。 有关详细信息,请参阅 容器资源生存期。
在 Aspire 向 AppHost 添加容器映像时,如前面的示例所示,该 mcr.microsoft.com/mssql/server 映像会在本地计算机上创建一个新的 SQL Server 实例。 对 SQL Server 资源生成器(sql 变量)的引用用于添加数据库。 首先将数据库命名为database,然后添加到ExampleProject。
将数据库资源添加到应用模型时,如果数据库尚不存在,则会创建该数据库。 数据库的创建依赖于 AppHost 事件 API,具体而言 ResourceReadyEvent。 换句话说,当sql资源准备就绪时,将引发事件并创建数据库资源。
SQL Server 资源包括默认凭据,其中username 为 sa,并且使用 password 方法生成了随机的 CreateDefaultPasswordParameter。
当 AppHost 运行时,密码存储在 AppHost 的机密存储中。 它已添加到 Parameters 部分,例如:
{
"Parameters:sql-password": "<THE_GENERATED_PASSWORD>"
}
参数名为 sql-password,但实际上仅仅是将资源名称格式化为带有 -password 后缀的形式。 有关详细信息,请参阅 ASP.NET Core 中应用机密在开发阶段的安全存储,以及 SQL Server 中添加带参数的资源。
在WithReference方法中配置一个名为ExampleProject的database连接。
提示
如果想要连接到现有 SQL Server,请改为调用 AddConnectionString。 有关详细信息,请参阅 引用现有资源。
使用数据库脚本添加 SQL Server 资源
默认情况下,当您添加SqlServerDatabaseResource时,它依赖于以下 SQL 脚本来创建数据库:
IF
(
NOT EXISTS
(
SELECT 1
FROM sys.databases
WHERE name = @DatabaseName
)
)
CREATE DATABASE [<QUOTED_DATABASE_NAME>];
若要更改默认脚本,请在数据库资源生成器上链式调用 WithCreationScript 方法:
var builder = DistributedApplication.CreateBuilder(args);
var sql = builder.AddSqlServer("sql")
.WithLifetime(ContainerLifetime.Persistent);
var databaseName = "app-db";
var creationScript = $$"""
IF DB_ID('{{databaseName}}') IS NULL
CREATE DATABASE [{{databaseName}}];
GO
-- Use the database
USE [{{databaseName}}];
GO
-- Create the todos table
CREATE TABLE todos (
id INT PRIMARY KEY IDENTITY(1,1), -- Unique ID for each todo
title VARCHAR(255) NOT NULL, -- Short description of the task
description TEXT, -- Optional detailed description
is_completed BIT DEFAULT 0, -- Completion status
due_date DATE, -- Optional due date
created_at DATETIME DEFAULT GETDATE() -- Creation timestamp
);
GO
""";
var db = sql.AddDatabase(databaseName)
.WithCreationScript(creationScript);
builder.AddProject<Projects.AspireApp_ExampleProject>("exampleproject")
.WithReference(db)
.WaitFor(db);
// After adding all resources, run the app...
builder.Build().Run();
前面的示例创建了一个名为app_db的数据库,其中包含一个todos表。 在创建数据库资源时执行 SQL 脚本。 脚本作为字符串传递给 WithCreationScript 方法,然后在 SQL Server 资源的上下文中执行。
添加具有数据容量的 SQL Server 资源
若要将数据卷添加到 SQL Server 资源,请在 WithDataVolume 资源上调用 SQL Server 方法:
var builder = DistributedApplication.CreateBuilder(args);
var sql = builder.AddSqlServer("sql")
.WithDataVolume();
var db = sql.AddDatabase("database");
builder.AddProject<Projects.AspireApp_ExampleProject>("exampleproject")
.WithReference(db)
.WaitFor(db);
// After adding all resources, run the app...
builder.Build().Run();
数据卷用于在容器的生命周期之外保留 SQL Server 数据。 数据卷装载在 /var/opt/mssql 路径的 SQL Server 容器中,当未提供 name 参数时,名称会随机生成。 有关数据量的详细信息,以及它们为何优于 绑定装载的详细原因,请参阅 Docker 文档:数据量。
警告
密码存储在数据卷中。 使用数据卷时,如果密码发生更改,则在删除数据卷之前,它将无法正常工作。
添加具有数据绑定挂载的 SQL Server 资源
若要将数据绑定挂载添加到 SQL Server 资源,请调用 WithDataBindMount 方法。
var builder = DistributedApplication.CreateBuilder(args);
var sql = builder.AddSqlServer("sql")
.WithDataBindMount(source: @"C:\SqlServer\Data");
var db = sql.AddDatabase("database");
builder.AddProject<Projects.AspireApp_ExampleProject>("exampleproject")
.WithReference(db)
.WaitFor(db);
// After adding all resources, run the app...
builder.Build().Run();
重要
与 卷相比,绑定 装载的数据功能有限,而 卷提供更好的性能、可移植性和安全性,因此它们更适用于生产环境。 但是,绑定装载允许直接访问和修改主机系统上的文件,非常适合在需要实时更改的情况下进行开发和测试。
数据绑定挂载依赖于主机的文件系统,以在容器重启时持久化SQL Server数据。 数据绑定装载被安装在 Windows 上的 C:\SqlServer\Data 路径上(或者在 /SqlServer/Data上的 Unix 路径上),位于 SQL Server 容器中的主机设备上。 欲了解更多有关数据绑定挂载的信息,请参阅 Docker 文档:绑定挂载。
添加带有参数的 SQL Server 资源
如果要显式提供容器映像使用的密码,可以将这些凭据作为参数提供。 请考虑以下替代示例:
var builder = DistributedApplication.CreateBuilder(args);
var password = builder.AddParameter("password", secret: true);
var sql = builder.AddSqlServer("sql", password);
var db = sql.AddDatabase("database");
builder.AddProject<Projects.AspireApp_ExampleProject>("exampleproject")
.WithReference(db)
.WaitFor(db);
// After adding all resources, run the app...
builder.Build().Run();
有关提供参数的详细信息,请参阅 外部参数。
连接至数据库资源
Aspire当 AppHost 运行时,可以从外部工具(例如 SQL Server Management Studio(SSMS)或 MSSQL for Visual Studio Code访问服务器的数据库资源。 数据库资源的连接字符串在依赖资源环境变量中可用,并使用 Aspire 仪表板:资源详细信息 窗格进行访问。 环境变量被命名为 ConnectionStrings__{name},其中 {name} 是数据库资源的名称,在本示例中为 database。 使用连接字符串从外部工具连接到数据库资源。 假设你有一个名为 todos 的数据库,其中包含单个 dbo.Todos 表。
若要从 SQL Server Management Studio 连接到数据库资源,请执行以下步骤:
打开 SSMS。
在“连接到 Server”对话框中,选择 “其他连接参数” 选项卡。
将连接字符串粘贴到“附加连接参数”字段中,然后选择“连接。
如果已连接,可以在 对象资源管理器中看到数据库资源:
有关详细信息,请参阅 SQL Server Management Studio:连接到服务器。
托管集成健康检查
SQL Server 托管集成会自动为 SQL Server 资源添加运行状况检查。 运行状况检查会验证 SQL Server 是否正在运行,并确保可以成功建立与其的连接。
托管集成依赖于 📦 AspNetCore.HealthChecks.SqlServer NuGet 包。
与非.NET 应用程序一起使用
SQL Server 托管集成可以与任何应用程序技术一起使用,而不仅限于 .NET 应用程序。 使用 WithReference 引用 SQL Server 资源时,连接信息会自动作为环境变量注入到引用的应用程序中。
对于不使用 客户端集成的应用程序,可以通过环境变量访问连接信息。 下面是如何为非.NET 应用程序配置环境变量的示例:
var builder = DistributedApplication.CreateBuilder(args);
var sql = builder.AddSqlServer("sql")
.WithLifetime(ContainerLifetime.Persistent);
var database = sql.AddDatabase("myDatabase");
// Example: Configure a non-.NET application with SQL Server access
var app = builder.AddExecutable("my-app", "python", "app.py", ".")
.WithReference(database) // Provides ConnectionStrings__myDatabase
.WithEnvironment(context =>
{
// Additional individual connection details as environment variables
context.EnvironmentVariables["SQL_SERVER"] = sql.Resource.PrimaryEndpoint.Property(EndpointProperty.Host);
context.EnvironmentVariables["SQL_PORT"] = sql.Resource.PrimaryEndpoint.Property(EndpointProperty.Port);
context.EnvironmentVariables["SQL_USERNAME"] = "sa";
context.EnvironmentVariables["SQL_PASSWORD"] = sql.Resource.PasswordParameter;
context.EnvironmentVariables["SQL_DATABASE"] = database.Resource.DatabaseName;
});
builder.Build().Run();
此配置为非.NET 应用程序提供了多个环境变量:
-
ConnectionStrings__myDatabase:完整的 SQL Server 连接字符串 -
SQL_SERVER:SQL Server 的主机名/IP 地址 -
SQL_PORT:SQL Server 正在侦听的端口号 -
SQL_USERNAME:用户名(通常sa为 SQL Server) -
SQL_PASSWORD:动态生成的密码 -
SQL_DATABASE:数据库的名称
然后,非.NET应用程序可以通过读取这些环境变量,使用相应的数据库驱动程序连接到SQL Server数据库(例如,pyodbc对于Python,node-mssql对于Node.js,或者通过database/sql与适用于Go的SQL Server驱动程序)。
Client 集成
若要开始 AspireSQL Server 客户端集成,请在使用 📦 客户端的应用程序项目中安装 Aspire NuGet 包。 SQL Server 客户端集成注册一个 SqlConnection 实例,你可以使用该实例与 SQL Server交互。
dotnet add package Aspire.Microsoft.Data.SqlClient
添加 SQL Server 客户端
在您的客户端消费项目中的 Program.cs 文件中,对任何 AddSqlServerClient 调用 IHostApplicationBuilder 扩展方法,以注册 SqlConnection,以便通过依赖注入容器进行使用。 该方法采用连接名称参数。
builder.AddSqlServerClient(connectionName: "database");
提示
参数 connectionName 必须与在 AppHost 项目中添加 SQL Server 数据库资源时使用的名称匹配。 换句话说,当你调用 AddDatabase 并提供 database 的名称时,在调用 AddSqlServerClient时应使用相同的名称。 有关详细信息,请参阅 添加 SQL Server 资源和数据库资源。
然后,可以使用依赖项注入检索 SqlConnection 实例。 例如,若要从示例服务检索连接,
public class ExampleService(SqlConnection connection)
{
// Use connection...
}
有关依赖项注入的详细信息,请参阅 .NET 依赖项注入。
添加键控客户< c0 />
在某些情况下,可能需要使用不同的连接名称注册多个 SqlConnection 实例。 若要注册密钥 SQL Server 客户端,请调用 AddKeyedSqlServerClient 方法:
builder.AddKeyedSqlServerClient(name: "mainDb");
builder.AddKeyedSqlServerClient(name: "loggingDb");
重要
使用密钥服务时,SQL Server 资源应配置两个命名数据库,一个用于 mainDb,另一个用于 loggingDb。
然后,可以使用依赖项注入检索 SqlConnection 实例。 例如,若要从示例服务检索连接,
public class ExampleService(
[FromKeyedServices("mainDb")] SqlConnection mainDbConnection,
[FromKeyedServices("loggingDb")] SqlConnection loggingDbConnection)
{
// Use connections...
}
有关密钥服务的详细信息,请参阅 .NET 依赖项注入:键式服务。
配置
Aspire SQL Server 集成提供了多个选项,用于根据项目的要求和约定配置连接。
使用连接字符串
使用 ConnectionStrings 配置部分中的连接字符串时,可以在调用 AddSqlServerClient 方法时提供连接字符串的名称:
builder.AddSqlServerClient(connectionName: "sql");
然后,从 ConnectionStrings 配置部分检索连接字符串:
{
"ConnectionStrings": {
"database": "Data Source=myserver;Initial Catalog=master"
}
}
有关如何设置此连接字符串格式的详细信息,请参阅 ConnectionString。
使用配置提供程序
Aspire
SQL Server 集成支持 Microsoft.Extensions.Configuration。 它使用 MicrosoftDataSqlClientSettings 键来从配置中加载 Aspire:Microsoft:Data:SqlClient。 以下代码片段是一个 appsettings.json 文件示例,用于配置某些选项:
{
"Aspire": {
"Microsoft": {
"Data": {
"SqlClient": {
"ConnectionString": "YOUR_CONNECTIONSTRING",
"DisableHealthChecks": false,
"DisableMetrics": true
}
}
}
}
}
有关完整的 SQL Server 客户端集成 JSON 架构,请参阅 Aspire。Microsoft.Data.SqlClient/ConfigurationSchema.json。
使用内联委托
还可以传递 Action<MicrosoftDataSqlClientSettings> configureSettings 代理来内联设置一些或全部选项,例如从代码中禁用健康状态检查:
builder.AddSqlServerClient(
"database",
static settings => settings.DisableHealthChecks = true);
Client 集成健康检查
默认情况下, Aspire 集成为所有服务启用 运行状况检查 。 有关详细信息,请参阅 Aspire 集成概述。
Aspire SQL Server 的集成:
- 在MicrosoftDataSqlClientSettings.DisableHealthChecks为
false时添加健康检查,以尝试连接到SQL Server。 - 与
/healthHTTP 终结点集成,该终结点要求所有已注册的健康检查都必须通过,应用才能被视为准备好接受流量。
可观测性和遥测
Aspire 集成会自动设置日志记录、跟踪和指标配置,这些配置有时称为 可观测性支柱。 有关集成可观测性和遥测的详细信息,请参阅 Aspire 集成概述。 根据支持服务,某些集成可能仅支持其中一些功能。 例如,某些集成支持日志记录和跟踪,但不支持指标。 也可以使用 配置 部分中介绍的技术禁用遥测功能。
日志记录
由于 Aspire的限制,SQL ServerMicrosoft.Data.SqlClient 集成目前默认不启用日志记录。
追踪
Aspire SQL Server 集成使用 OpenTelemetry输出以下跟踪活动:
OpenTelemetry.Instrumentation.SqlClient
指标
Aspire SQL Server 集成将通过 OpenTelemetry发出以下指标:
- Microsoft.Data.SqlClient.EventSource
active-hard-connectionshard-connectshard-disconnectsactive-soft-connectssoft-connectssoft-disconnectsnumber-of-non-pooled-connectionsnumber-of-pooled-connectionsnumber-of-active-connection-pool-groupsnumber-of-inactive-connection-pool-groupsnumber-of-active-connection-poolsnumber-of-inactive-connection-poolsnumber-of-active-connectionsnumber-of-free-connectionsnumber-of-stasis-connectionsnumber-of-reclaimed-connections