Azure Function V4 .NET隔离模式下如何读写CosmosDB?
.NET隔离模式Azure Function V4中CosmosDB读写实现方案
前置准备
- 安装NuGet包:
Microsoft.Azure.Cosmos(直接使用Cosmos官方SDK,不再依赖WebJobs特性) - 在
local.settings.json或Azure配置中添加CosmosDB连接字符串,示例命名为CosmosDbConnectionString
读取函数(根据documentId查询)
创建HTTP触发函数,通过构造函数注入CosmosClient,利用SDK直接读取目标文档:
using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using Microsoft.Azure.Cosmos; using System.Net; public class CosmosDbReadFunction { private readonly CosmosClient _cosmosClient; private readonly string _databaseId = "你的数据库ID"; private readonly string _containerId = "你的容器ID"; public CosmosDbReadFunction(CosmosClient cosmosClient) { _cosmosClient = cosmosClient; } [Function("GetMyDocById")] public async Task<HttpResponseData> Run( [HttpTrigger(AuthorizationLevel.Function, "get", Route = "mydoc/{documentId}")] HttpRequestData req, string documentId) { var container = _cosmosClient.GetContainer(_databaseId, _containerId); try { // 此处假设分区键与documentId一致,需根据实际容器配置调整 var response = await container.ReadItemAsync<MyDoc>(documentId, new PartitionKey(documentId)); var res = req.CreateResponse(HttpStatusCode.OK); await res.WriteAsJsonAsync(response.Resource); return res; } catch (CosmosException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { var res = req.CreateResponse(HttpStatusCode.NotFound); await res.WriteStringAsync("文档不存在"); return res; } } } public class MyDoc { public string Id { get; set; } // 自定义其他业务属性 }
写入函数(接收MyDoc并写入)
通过Cosmos SDK执行Upsert操作(自动处理创建或更新):
using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using Microsoft.Azure.Cosmos; using System.Net; using System.Text.Json; public class CosmosDbWriteFunction { private readonly CosmosClient _cosmosClient; private readonly string _databaseId = "你的数据库ID"; private readonly string _containerId = "你的容器ID"; public CosmosDbWriteFunction(CosmosClient cosmosClient) { _cosmosClient = cosmosClient; } [Function("CreateOrUpdateMyDoc")] public async Task<HttpResponseData> Run( [HttpTrigger(AuthorizationLevel.Function, "post", Route = "mydoc")] HttpRequestData req) { var myDoc = await JsonSerializer.DeserializeAsync<MyDoc>(req.Body); if (myDoc == null || string.IsNullOrEmpty(myDoc.Id)) { var res = req.CreateResponse(HttpStatusCode.BadRequest); await res.WriteStringAsync("无效的文档数据,Id不能为空"); return res; } var container = _cosmosClient.GetContainer(_databaseId, _containerId); // Upsert自动判断文档是否存在,存在则更新,不存在则创建 var response = await container.UpsertItemAsync(myDoc, new PartitionKey(myDoc.Id)); var res = req.CreateResponse(HttpStatusCode.Created); await res.WriteAsJsonAsync(response.Resource); return res; } }
配置CosmosClient依赖注入
在Program.cs中注册CosmosClient,确保可通过构造函数注入:
using Microsoft.Azure.Functions.Worker; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; var host = new HostBuilder() .ConfigureFunctionsWorkerDefaults() .ConfigureServices(services => { services.AddSingleton<CosmosClient>(sp => { var configuration = sp.GetRequiredService<IConfiguration>(); var connectionString = configuration["CosmosDbConnectionString"]; return new CosmosClient(connectionString); }); }) .Build(); host.Run();
关键说明
- 不再依赖WebJobs的
[CosmosDB]特性,直接使用官方Cosmos SDK,灵活性更强 - 依赖注入
CosmosClient是推荐方案,避免重复创建客户端实例导致资源浪费 - 分区键需与容器配置完全匹配,示例中假设分区键为
Id,需根据实际场景调整 - 若仅需创建文档可使用
CreateItemAsync,仅更新则用ReplaceItemAsync,UpsertItemAsync为通用场景最优选择
内容的提问来源于stack exchange,提问作者AndyW
相关产品推荐
相关产品推荐

