Aspire SQL Server 集成

包含:托管集成已包含 - Client 集成已包含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 资源包括默认凭据,其中usernamesa,并且使用 password 方法生成了随机的 CreateDefaultPasswordParameter

当 AppHost 运行时,密码存储在 AppHost 的机密存储中。 它已添加到 Parameters 部分,例如:

{
  "Parameters:sql-password": "<THE_GENERATED_PASSWORD>"
}

参数名为 sql-password,但实际上仅仅是将资源名称格式化为带有 -password 后缀的形式。 有关详细信息,请参阅 ASP.NET Core 中应用机密在开发阶段的安全存储,以及 SQL Server 中添加带参数的资源。

WithReference方法中配置一个名为ExampleProjectdatabase连接。

提示

如果想要连接到现有 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 连接到数据库资源,请执行以下步骤:

  1. 打开 SSMS。

  2. 在“连接到 Server”对话框中,选择 “其他连接参数” 选项卡。

  3. 将连接字符串粘贴到“附加连接参数”字段中,然后选择“连接

    SQL Server Management Studio:连接到Server 对话框。

  4. 如果已连接,可以在 对象资源管理器中看到数据库资源:

    SQL Server Management Studio:连接到数据库。

有关详细信息,请参阅 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.DisableHealthChecksfalse时添加健康检查,以尝试连接到SQL Server。
  • /health HTTP 终结点集成,该终结点要求所有已注册的健康检查都必须通过,应用才能被视为准备好接受流量。

可观测性和遥测

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

日志记录

由于 Aspire的限制,SQL ServerMicrosoft.Data.SqlClient 集成目前默认不启用日志记录。

追踪

Aspire SQL Server 集成使用 OpenTelemetry输出以下跟踪活动:

  • OpenTelemetry.Instrumentation.SqlClient

指标

Aspire SQL Server 集成将通过 OpenTelemetry发出以下指标:

  • Microsoft.Data.SqlClient.EventSource
    • active-hard-connections
    • hard-connects
    • hard-disconnects
    • active-soft-connects
    • soft-connects
    • soft-disconnects
    • number-of-non-pooled-connections
    • number-of-pooled-connections
    • number-of-active-connection-pool-groups
    • number-of-inactive-connection-pool-groups
    • number-of-active-connection-pools
    • number-of-inactive-connection-pools
    • number-of-active-connections
    • number-of-free-connections
    • number-of-stasis-connections
    • number-of-reclaimed-connections

另请参阅