拓冰建站拓冰建站
首页 / 资讯中心 / 正文

EF Core Azure Cosmos DB 提供商详解:UseCosmos 配置、连接选项与 Cosmos 提供方源码剖析

EF Core Azure Cosmos DB 提供商详解UseCosmos 配置、连接选项与 Cosmos 提供方源码剖析【免费下载链接】efcoreEF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.项目地址: https://gitcode.com/GitHub_Trending/ef/efcoreMicrosoft.EntityFrameworkCore.Cosmos是 EF Core 针对 Azure Cosmos DB 的数据库提供程序包provider package它让DbContext可以直接映射到 Cosmos DB 的数据库、容器与文档并以 LINQ 表达式的形式执行查询与更新。本文以仓库中该包的 README 为骨架逐层展开UseCosmos的各种重载、CosmosDbContextOptionsBuilder提供的全套连接与行为选项、会话一致性管理、依赖注入注册方式并结合 提供程序源码 说明这些配置在底层是如何被存储和消费的适合准备在 .NET 应用中接入 Cosmos DB 的开发者。一、包定位与基本用法从 src/EFCore.Cosmos/README.md 可以看到这个包的核心职责只有一句话作为 EF Core 的数据库提供程序接入 Azure Cosmos DB。最典型的使用方式是在DbContext.OnConfiguring中调用UseCosmos扩展方法protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) optionsBuilder.UseCosmos( https://localhost:8081, C2y6yDjf5/Rob0N8A7Cgv30VRDJIWEHLM4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw, databaseName: OrdersDB);其中localhost:8081是 Cosmos DB 本地模拟环境Cosmos DB Emulator的默认端点第二个参数是账号密钥第三个参数是要使用的数据库名。关于 EF 系列 NuGet 包的安装与入门以及该提供程序的完整功能文档数据类型映射、保存行为、查询翻译等仓库 README 指向了 EF Core 官方文档站遇到 Bug 或问题时官方建议通过项目仓库的 Issue 渠道提交反馈。UseCosmos 的全部重载源码中UseCosmos定义了四组核心重载每组分泛型TContext与非泛型两个版本见 CosmosDbContextOptionsExtensions重载形式参数适用场景UseCosmos(ActionCosmosDbContextOptionsBuilder)仅配置委托只声明使用 Cosmos 提供方连接细节留待后续调用补齐UseCosmos(string accountEndpoint, string accountKey, string databaseName, ...)端点 账号密钥 数据库名经典的主机名/密钥认证方式即 README 示例UseCosmos(string accountEndpoint, TokenCredential tokenCredential, string databaseName, ...)端点 Azure 令牌凭据 数据库名基于 Microsoft Entra ID 的免密钥认证UseCosmos(string connectionString, string databaseName, ...)连接字符串 数据库名连接信息已统一管理在配置源中所有重载末尾都带一个可选的cosmosOptionsAction委托用于在同一处链式追加 Cosmos 专属配置。从源码可以确认两个细节参数校验。账号密钥重载会执行Check.NotEmpty(accountKey)与Check.NotEmpty(databaseName)连接字符串重载则会校验连接串非空密钥重载与令牌重载之间是二选一关系端点与密钥/凭据必须成对提供。配置以扩展对象形式落库。每次调用都会取出或新建一个CosmosOptionsExtension通过WithAccountEndpoint/WithTokenCredential/WithDatabaseName等克隆式方法改写后经IDbContextOptionsBuilderInfrastructure.AddOrUpdateExtension写回 options。CosmosOptionsExtension实现了IDbContextOptionsExtension接口见 CosmosDbOptionExtension.cs它是内部 API负责保存端点、密钥、令牌凭据、连接串、区域、连接模式、超时等全部连接信息。值得注意的是WithAccountEndpoint内部会把_connectionString置空反之亦然——从源码结构看端点密钥与连接字符串两种连接方式在选项层面互斥后者总是以最后一次设置为准。另外UseCosmos内部还有一段容易被忽略的逻辑ConfigureWarnings方法会强制把CosmosEventId.BulkExecutionWithTransactionalBatch这个警告的行为设为WarningBehavior.Throw。也就是说当批量执行bulk execution与事务性批处理Transactional Batches同时启用时EF 会直接抛异常而不是仅告警因为 Cosmos SDK 的 bulk 模式本身无法执行 Transactional Batches。二、CosmosDbContextOptionsBuilder全套连接与行为选项UseCosmos委托中传入的CosmosDbContextOptionsBuilder是 Cosmos 提供方专属的配置入口完整定义见 CosmosDbContextOptionsBuilder.cs。它提供的方法可分为四组1. 执行策略与地理复制ExecutionStrategy(FuncExecutionStrategyDependencies, IExecutionStrategy)自定义执行策略控制失败重试等行为。Region(string region)指定单个地理复制区域名将请求路由到该区域。PreferredRegions(IReadOnlyListstring regions)指定多个优先区域用于跨区域高可用场景。LimitToEndpoint(bool enable true)把操作限制在提供的端点内不做区域路由。2. 客户端与网络HttpClientFactory(FuncHttpClient?)提供自定义HttpClient工厂。官方注释明确提醒使用静态 lambda避免每次请求都新建实例。ConnectionMode(ConnectionMode connectionMode)选择网关Gateway还是直连Direct/TCP模式来自 Cosmos SDK 的ConnectionMode枚举。WebProxy(IWebProxy proxy)为 Web 请求配置代理信息。3. 超时与连接上限Direct/TCP 调优参数RequestTimeout(TimeSpan)等待网络对端响应的请求超时。OpenTcpConnectionTimeout(TimeSpan)建立 TCP 连接允许的最长时间。IdleTcpConnectionTimeout(TimeSpan)空闲连接多久后被主动关闭。GatewayModeMaxConnectionLimit(int)目标服务端点允许的最大并发连接数网关模式下有效。MaxTcpConnectionsPerEndpoint(int)对每个 Cosmos DB 后端可打开的 TCP 连接数上限。MaxRequestsPerTcpConnection(int)单条 TCP 连接上允许同时在途的请求数超过该值时 Direct/TCP 客户端会再开新连接。源码注释特别指出MaxRequestsPerTcpConnection × MaxTcpConnectionsPerEndpoint共同决定了发往单个后端的并发请求上限这对高并发写入场景的吞吐调优很重要。4. 行为开关SessionTokenManagementMode(SessionTokenManagementMode mode)会话令牌管理方式下一节详述。BulkExecutionAllowed(bool enabled true)开启 Cosmos SDK 的 bulk execution 功能。源码注释给出了明确的使用边界该功能可提升小写入的吞吐但可能增加延迟只推荐给高吞吐、不敏感延迟的场景并且由于 Transactional Batches 不能以 bulk 方式执行EF 批处理内的操作不会走 bulk 通道——注释甚至建议若要确保操作全部走 bulk可将AutoTransactionBehavior设为Never来关闭批处理。这与前文UseCosmos强制把BulkExecutionWithTransactionalBatch警告提升为异常的设计是配套的。ContentResponseOnWriteEnabled(bool enabled true)控制写入操作Create、Upsert、Patch、Replace的响应是否回传完整资源体。源码注释说明 EntityFrameworkCore 自 11.0 起默认值为false即写入后不回传资源体以减少网络与序列化开销并且该方法已被标记[Obsolete(Enabling ContentResponseOnWrite currently has no benefit for EF Core.)]——当前版本中开启它对 EF 已无收益新代码不应再调用。所有选项最终都通过WithOption方法写入同一个CosmosOptionsExtension该扩展实现了不可变克隆语义每次设置都基于旧实例克隆再修改避免影响其他正在使用同一 options 的对象。在 CosmosDbOptionExtension.cs 中可以看到每个选项对应的私有字段例如_preferredRegions、_gatewayModeMaxConnectionLimit、_idleTcpConnectionTimeout等以及会话令牌模式字段_sessionTokenManagementMode的默认值SessionTokenManagementMode.FullyAutomatic——即不显式设置时使用 SDK 的自动会话管理。三、会话一致性SessionTokenManagementMode 与令牌 APICosmos DB 在会话一致性Session Consistency级别下依赖 session token 保证自己读自己的写。EF Core 默认把这件事完全交给 Cosmos SDK 处理但在负载均衡等无会话亲和性的部署中需要由应用层接管令牌的流转。四种管理模式的语义枚举定义见 SessionTokenManagementMode.csFullyAutomatic默认使用 Cosmos SDK 的自动会话令牌管理EF 不跟踪、不解析返回的令牌此时调用UseSessionTokens/GetSessionTokens会抛出异常。SemiAutomatic允许用UseSessionTokens按容器覆盖 SDK 的自动管理未被覆盖的容器仍走 SDK 自动模式。EF 会跟踪并解析响应中的令牌可用GetSessionTokens取回。Manual完全接管只使用UseSessionTokens显式提供的令牌未提供令牌的容器将不带令牌访问即放弃会话一致性。EnforcedManual与Manual相同但若执行读操作前未调用过UseSessionTokens直接抛异常用于防止应用配置疏漏导致的隐性降级。DatabaseFacade 上的令牌操作 API令牌的实际读写入口是 CosmosDatabaseFacadeExtensions 中基于DbContext.Database的一组扩展方法读取GetSessionToken()返回默认容器的复合令牌无则nullGetSessionTokens()返回按容器索引的IReadOnlyDictionarystring, string?。设置UseSessionToken(string)/UseSessionTokens(IReadOnlyDictionarystring, string?)。追加AppendSessionToken(string)/AppendSessionTokens(IReadOnlyDictionarystring, string)用于多个实例各自跟踪令牌后合并。从源码结构看这些方法都委托给ISessionTokenStorage通过CosmosDatabaseWrapper暴露因此只有在SemiAutomatic及以上模式下调用才有意义若提供方不是 CosmosGetService会抛出CosmosNotInUse异常。四、依赖注入注册与内部服务结构在 ASP.NET Core 等使用 DI 的场景中不需要手写OnConfiguring而是用 CosmosServiceCollectionExtensions 提供的快捷方法services.AddCosmosAppDbContext( connectionString, OrdersDB, cosmosOptionsAction: cosmos cosmos .ConnectionMode(ConnectionMode.Direct) .MaxTcpConnectionsPerEndpoint(50) .MaxRequestsPerTcpConnection(30));AddCosmosTContext本质上是对AddDbContextTContext的包装先执行用户传入的optionsAction再调用options.UseCosmos(connectionString, databaseName, cosmosOptionsAction)。源码注释明确说明它是快捷方式不支持全部选项需要完整控制如 Lifetime 管理、命名上下文时应直接使用AddDbContext系列方法。同文件中的AddEntityFrameworkCosmos(this IServiceCollection)则带有[EditorBrowsable(EditorBrowsableState.Never)]标记注释警告多数应用不应调用它——它只在为UseInternalServiceProvider手工构建内部服务提供者时才需要。不过它恰好是阅读提供程序架构的索引从中可以看到 EF 为 Cosmos 注册的关键服务CosmosExecutionStrategyFactory、CosmosTransactionManager执行策略与事务管理Cosmos 的事务语义与关系型数据库不同由CosmosTransactionManager适配CosmosModelValidator、CosmosModelRuntimeInitializer、CosmosConventionSetBuilder模型校验、运行时模型初始化与默认约定CosmosTypeMappingSource、CosmosQueryableMethodTranslatingExpressionVisitorFactory、CosmosShapedQueryCompilingExpressionVisitorFactory、CosmosQueryTranslationPreprocessorFactory等类型映射与查询翻译管线负责把 LINQ 表达式翻译成 Cosmos 查询CosmosClientWrapper、SingletonCosmosClientWrapper、QuerySqlGeneratorFactory、SessionTokenStorageFactory、CosmosStructuralTypeSerializerProvider底层客户端封装、查询生成、令牌存储与文档序列化。也就是说应用层只需配置 optionsLINQ 翻译、令牌存储、客户端生命周期这些复杂机制全部由该服务注册清单承担。五、运行时访问底层资源需要绕过 EF 直接操作 Cosmos例如批量管理容器、查看资源用量时CosmosDatabaseFacadeExtensions还提供了三个工具方法GetCosmosClient()返回该DbContext背后的CosmosClient实例实现上是通过内部单例ISingletonCosmosClientWrapper获取保证同一 options 下复用同一个客户端GetCosmosDatabaseId()从 options 扩展中读出配置时使用的数据库名IsCosmos()判断当前提供方是否为 Cosmos。源码注释提醒该方法只能在DbContext完成配置之后使用OnConfiguring内不可用因为它依赖 options 最终确定的提供方名。六、小结与延伸阅读回到 README 给出的信息面Microsoft.EntityFrameworkCore.Cosmos包的最小使用契约就是UseCosmos(端点, 密钥, 数据库名)三要素而仓库源码揭示的完整能力面是——四组连接重载、约二十个CosmosDbContextOptionsBuilder网络与行为选项、四种会话令牌管理模式、DI 快捷注册以及一套面向DatabaseFacade的令牌/客户端访问 API。EF 包的安装入门与该提供程序的数据类型、保存行为、查询能力等进阶特性建议进一步阅读 EF Core 官方文档中 Getting started with EF Core 与 Azure Cosmos DB Provider 两篇指南发现 Bug 时可提交项目仓库 Issue。关键源码索引配置入口与重载CosmosDbContextOptionsExtensions.cs选项定义CosmosDbContextOptionsBuilder.cs选项存储内部 APICosmosDbOptionExtension.cs会话令牌模式SessionTokenManagementMode.cs令牌与客户端访问CosmosDatabaseFacadeExtensions.csDI 注册CosmosServiceCollectionExtensions.cs【免费下载链接】efcoreEF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.项目地址: https://gitcode.com/GitHub_Trending/ef/efcore创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门