Aspire 集成指南:使用 Aspire.Microsoft.EntityFrameworkCore.SqlServer 为 EF Core 接入 Azure SQL / SQL Server
2026/9/18 13:41:09 网站建设 项目流程

Aspire 集成指南:使用 Aspire.Microsoft.EntityFrameworkCore.SqlServer 为 EF Core 接入 Azure SQL / SQL Server

【免费下载链接】aspireAspire is the tool for code-first, extensible, observable dev and deploy.项目地址: https://gitcode.com/GitHub_Trending/as/aspire

本篇文章围绕 .NET Aspire 官方组件Aspire.Microsoft.EntityFrameworkCore.SqlServer展开,讲解如何在 Aspire 应用中为 Entity Framework Core 的DbContext一键接入 Azure SQL 与 MS SQL Server 数据库。读完本文你将掌握组件的安装与注册方式、连接字符串与配置提供程序的使用、Microsoft Entra ID(Azure AD)认证的底层机制,以及 AppHost 中Aspire.Hosting.SqlServer的端到端编排用法,并了解连接池、重试、健康检查与 OpenTelemetry 遥测是如何被自动开启的。

组件概述:一条命令获得完整的 SQL Server 数据访问能力

该组件的作用是:在基于IHostApplicationBuilder构建的 Aspire 应用中,注册一个连接 Azure SQL / MS SQL Server 数据库的 Entity Framework CoreDbContext服务,并自动启用以下能力(见 AspireSqlServerEFCoreSqlClientExtensions.cs):

  • DbContext 连接池:通过AddDbContextPool<TContext>注册,减少实例创建开销;
  • 连接弹性(重试):默认开启EnableRetryOnFailure(),对失败的数据库命令自动重试;
  • 健康检查:注册AddDbContextCheck<TContext>,可供 Dashboard 与探针使用;
  • 日志:沿用 EF Core 自带的日志机制(无需额外注册 LoggerFactory,参见 EF Core 文档说明);
  • 遥测:通过AddSqlClientInstrumentation()接入 OpenTelemetry SQL Client 插桩,收集追踪数据。

从 csproj(Aspire.Microsoft.EntityFrameworkCore.SqlServer.csproj)可以看到,它依赖Microsoft.EntityFrameworkCore.SqlServerMicrosoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCoreOpenTelemetry.Extensions.HostingOpenTelemetry.Instrumentation.SqlClient等包,这些依赖共同构成了上述能力栈。

快速开始

环境前提

  • 一个可访问的 Azure SQL 或 MS SQL Server 数据库;
  • 数据库对应的连接字符串。

安装 NuGet 包

在目标项目中通过 .NET CLI 安装组件:

dotnet add package Aspire.Microsoft.EntityFrameworkCore.SqlServer

用法示例

方式一:AddSqlServerDbContext —— 注册即用

AppHost项目的AppHost.cs中(注意:实际生产项目中,注册代码应写在引用该连接字符串的服务项目Program.cs里),调用AddSqlServerDbContext<TContext>扩展方法,通过依赖注入容器注册DbContext。方法接收一个连接名称参数:

builder.AddSqlServerDbContext<MyDbContext>("sqldata");

随后即可通过构造函数注入获取MyDbContext,例如在 Web API 控制器中:

private readonly MyDbContext _context; public ProductsController(MyDbContext context) { _context = context; }

方式二:EnrichSqlServerDbContext —— 为已注册的 DbContext 补全能力

如果因为业务需要,你已经用其他方式注册了DbContext(例如想自定义UseSqlServer的选项),则改用EnrichSqlServerDbContext为它补齐重试、健康检查与遥测能力:

var connectionString = builder.Configuration.GetConnectionString("catalogdb"); builder.Services.AddDbContextPool<CatalogDbContext>(dbContextOptionsBuilder => dbContextOptionsBuilder.UseSqlServer(connectionString)); builder.EnrichSqlServerDbContext<CatalogDbContext>();

两种方式的行为差异(从源码可以确认):

  • AddSqlServerDbContext会先调用EnsureDbContextNotRegistered<TContext>(),若DbContext已被注册会抛出InvalidOperationException,提示改用Enrich方法(测试 AspireSqlServerEFCoreSqlClientExtensionsTests.cs 中的ThrowsWhenDbContextIsRegisteredBeforeAspireComponent验证了这一点);
  • EnrichSqlServerDbContext不会从ConnectionStrings配置节读取连接字符串,因为它被调用时DbContext已经注册完成,连接字符串应已在注册处配置好。

EnrichSqlServerDbContext在重试配置上有更精细的处理(见源码 AspireSqlServerEFCoreSqlClientExtensions.cs):

  • 若当前已存在SqlServerRetryingExecutionStrategy或其子类(用户自定义重试策略),则保留用户的策略,不会覆盖;
  • 若用户配置了自定义ExecutionStrategy,而DisableRetry未设为true,会抛出异常提示需要显式禁用重试,避免两种策略冲突;
  • 若配置的CommandTimeoutDbContextOptions中已有的值冲突,同样会抛出InvalidOperationException提示。

配置详解

组件提供了多种配置 SQL 连接的方式,可根据项目约定灵活选择。所有配置最终汇聚到MicrosoftEntityFrameworkCoreSqlServerSettings(见 MicrosoftEntityFrameworkCoreSqlServerSettings.cs),其属性如下:

属性类型默认值说明
ConnectionStringstring?null目标 SQL Server 数据库的连接字符串
DisableRetryboolfalse是否禁用连接重试(默认开启重试)
DisableHealthChecksboolfalse是否禁用数据库健康检查(默认开启)
DisableTracingboolfalse是否禁用 OpenTelemetry 追踪(默认开启)
CommandTimeoutint?null命令执行等待时间(秒),未设置时使用 EF Core 默认值

使用连接字符串

组件从ConnectionStrings配置节读取连接字符串,只需在调用时传入连接名:

builder.AddSqlServerDbContext<MyDbContext>("myConnection");

对应的配置(如 appsettings.json):

{ "ConnectionStrings": { "myConnection": "Data Source=myserver;Initial Catalog=master" } }

连接字符串的具体格式说明可参考 SqlConnection.ConnectionString 文档。

从源码看,AddSqlServerDbContext读取设置的顺序是:先通过GetDbContextSettings从配置段绑定设置(详见下文“配置优先级”),随后若ConnectionStrings中存在对应连接名,则用该连接字符串覆盖settings.ConnectionString,最后再执行configureSettings委托——因此代码中显式设置的连接字符串优先级最高(测试ConnectionStringCanBeSetInCodeConnectionNameWinsOverConfigSection分别验证了这两种优先级关系)。

Microsoft Entra ID(Azure AD)认证

要使用 Entra ID 连接 Azure SQL(例如托管标识场景),连接字符串需指定认证模式,如:

Authentication="Active Directory Default"

这正是Aspire.Hosting.Azure.Sql集成默认生成的连接字符串形态。

底层机制(重点):自 Microsoft.Data.SqlClient 7.0 起,Entra ID 认证提供程序不再内置在核心驱动中,而是拆分到了独立的 Microsoft.Data.SqlClient.Extensions.Azure 包。本组件在 csproj 中显式引用了该包(见 Aspire.Microsoft.EntityFrameworkCore.SqlServer.csproj),因此这类连接字符串开箱即用,无需额外安装包或编写注册代码,同时组件也会传递引入Azure.Identity

测试 AspireSqlServerEFCoreSqlClientExtensionsTests.cs 中的EntraIdAuthenticationProviderIsRegistered专门验证了ActiveDirectoryDefaultActiveDirectoryManagedIdentity两种认证提供程序都能在组件内正常解析,防止后续依赖升级时回归。

使用配置提供程序

组件支持Microsoft.Extensions.Configuration,从配置键Aspire:Microsoft:EntityFrameworkCore:SqlServer加载MicrosoftEntityFrameworkCoreSqlServerSettings。例如 appsettings.json 中禁用健康检查与追踪:

{ "Aspire": { "Microsoft": { "EntityFrameworkCore": { "SqlServer": { "DisableHealthChecks": true, "DisableTracing": true } } } } }

完整的可配置项与默认值可参考组件自带的 ConfigurationSchema.json,其中还列出了Microsoft.EntityFrameworkCore.*各分类的日志级别定义,便于 IDE 提供智能提示。

使用内联委托

也可以通过Action<MicrosoftEntityFrameworkCoreSqlServerSettings> configureSettings委托在代码中内联设置部分或全部选项,例如禁用健康检查:

builder.AddSqlServerDbContext<MyDbContext>("sqldata", settings => settings.DisableHealthChecks = true);

或配合Enrich方法:

builder.EnrichSqlServerDbContext<MyDbContext>(settings => settings.DisableHealthChecks = true);

配置优先级(从源码与测试归纳)

  1. 连接字符串configureSettings中显式赋值 >ConnectionStrings:{连接名}>Aspire:...:SqlServer配置段;
  2. 普通设置项(如 CommandTimeout):上下文级配置段Aspire:Microsoft:EntityFrameworkCore:SqlServer:{DbContext类型名}优先于连接级配置段Aspire:Microsoft:EntityFrameworkCore:SqlServer:{连接名},两者都优先于全局默认段Aspire:Microsoft:EntityFrameworkCore:SqlServer
  3. Add 与 Enrich 的差异AddSqlServerDbContext在内部调用UseSqlServer并应用设置;EnrichSqlServerDbContext只做“补充”,不会触碰连接字符串。

这些规则分别被测试AddSqlServerDbContext_WithConnectionNameAndSettings_AppliesConnectionSpecificSettingsAddSqlServerDbContext_WithConnectionSpecificAndContextSpecificSettings_PrefersContextSpecificCommandTimeoutFromBuilderWinsOverOthers所覆盖。

自定义 DbContextOptions

AddSqlServerDbContext还支持第三个可选参数Action<DbContextOptionsBuilder> configureDbContextOptions,用于进一步定制 EF Core 选项,例如设置批大小:

builder.AddSqlServerDbContext<MyDbContext>("sqldata", configureDbContextOptions: optionsBuilder => { optionsBuilder.UseSqlServer(sqlBuilder => { sqlBuilder.MinBatchSize(123); }); });

源码中该委托在内部UseSqlServer之后执行(见 AspireSqlServerEFCoreSqlClientExtensions.cs),因此可用于覆盖默认行为;测试CanConfigureDbContextOptions验证了自定义选项、配置段中的CommandTimeout(示例中为 608 秒)以及默认重试策略会同时生效。

AppHost 扩展:在编排层注册 SQL Server

若要在 AppHost 中声明式地创建 SQL Server 容器资源并自动注入连接信息,需要安装宿主侧的集成包:

dotnet add package Aspire.Hosting.SqlServer

然后在 AppHost 的AppHost.cs中注册数据库资源,并通过WithReference将连接配置注入到服务项目:

var sql = builder.AddSqlServer("sql").AddDatabase("sqldata"); var myService = builder.AddProject<Projects.MyService>() .WithReference(sql);

其中AddSqlServer在 SqlServerBuilderExtensions.cs 中创建SqlServerServerResourceAddDatabase在其上追加SqlServerDatabaseResource

WithReference会在MyService项目中生成名为sqldata的连接配置。随后在MyServiceProgram.cs中即可消费该连接:

builder.AddSqlServerDbContext<MyDbContext>("sqldata");

这样 AppHost 编排层与服务消费层通过连接名(sqldata)实现了解耦:数据库的部署形态(本地容器、Azure SQL 等)由 AppHost 决定,而服务代码只需关注连接名。

小结

Aspire.Microsoft.EntityFrameworkCore.SqlServer组件把 EF Core 接入 SQL Server 的常见横切关注点(连接池、重试、健康检查、日志、遥测、Entra ID 认证)收敛为一次注册调用,并通过“配置段 + 连接名 + 内联委托”的多层配置体系提供了充分的灵活性;配合Aspire.Hosting.SqlServer的 AppHost 编排,可以快速构建出可观测、可弹性伸缩的数据库访问链路。需要深入研究的读者可继续阅读:

  • 组件入口实现:AspireSqlServerEFCoreSqlClientExtensions.cs
  • 设置模型:MicrosoftEntityFrameworkCoreSqlServerSettings.cs
  • 配置 Schema:ConfigurationSchema.json
  • 行为测试:AspireSqlServerEFCoreSqlClientExtensionsTests.cs
  • AppHost 侧集成:SqlServerBuilderExtensions.cs

【免费下载链接】aspireAspire is the tool for code-first, extensible, observable dev and deploy.项目地址: https://gitcode.com/GitHub_Trending/as/aspire

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询