使用Microsoft Graph SDK批量获取AD用户及经理信息的性能优化问题
优化AAD组成员及经理查询性能的解决方案
一、批量获取用户经理(避免N+1请求)
方案1:查询组成员时直接展开经理信息
直接在查询组内成员的请求中通过$expand=manager加载经理数据,一次性完成查询,彻底消除循环逐个请求的性能问题。同时通过$select筛选需要的字段,减少数据传输量:
// 替换原有的组查询代码,直接获取包含经理的用户列表 var groupMembers = await graphClient.Groups[groupId].Members .GetAsync(requestConfig => { // 只加载用户类型的成员,无需后续类型判断 requestConfig.QueryParameters.Filter = "odata.type eq '#microsoft.graph.user'"; // 展开经理信息,并仅选择需要的字段(按需调整) requestConfig.QueryParameters.Expand = new[] { "manager" }; requestConfig.QueryParameters.Select = new[] { "id", "displayName", "manager/displayName" }; }); // 此时每个User对象已包含Manager属性,无需额外请求 foreach (var user in groupMembers.Value.OfType<User>()) { var managerName = user.Manager?.AdditionalData["displayName"]?.ToString(); // 使用managerName即可 }
方案2:使用批量请求(Batch)批量获取经理
如果无法在组查询时展开经理(比如权限限制或特殊业务逻辑),可以用Graph Batch API一次性批量请求所有用户的经理,将N次HTTP请求压缩为少数几次(每批最多20个请求):
// 先收集组内所有用户ID var userIds = groupMembers.Value.OfType<User>().Select(u => u.Id).ToList(); var userManagerMap = new Dictionary<string, string>(); // 分批次处理,Graph Batch单批最多支持20个请求 foreach (var batchIds in userIds.Chunk(20)) { var batchContent = new BatchRequestContent(); foreach (var userId in batchIds) { // 创建获取经理的请求,并关联用户ID作为批次标识 var managerRequest = graphClient.Users[userId].Manager.ToGetRequestInformation(); batchContent.AddBatchRequestStep(managerRequest, userId); } // 发送批量请求 var batchResponse = await graphClient.Batch.PostAsync(batchContent); // 解析批量响应,映射用户ID与经理姓名 foreach (var userId in batchIds) { if (await batchResponse.TryGetResponseByIdAsync<User>(userId, out var manager)) { userManagerMap[userId] = manager.DisplayName; } } } // 后续直接从字典中获取经理姓名,无需修改原User对象 foreach (var user in groupMembers.Value.OfType<User>()) { if (userManagerMap.TryGetValue(user.Id, out var managerName)) { // 使用managerName } }
二、禁用Graph SDK的变更追踪
如果必须保留原有的逐个请求逻辑,可以通过配置Graph客户端禁用变更追踪,消除u.Manager = manager时的性能损耗。在创建GraphServiceClient时,指定NullBackingStoreFactory:
// 初始化Graph客户端时禁用变更追踪 var graphClient = new GraphServiceClient(yourAuthenticationProvider, options => { options.BackingStoreFactory = new NullBackingStoreFactory(); });
注意:禁用变更追踪后,SDK不再跟踪模型属性的修改,因此如果后续需要修改用户数据并调用Graph的更新接口,将无法自动生成增量更新请求,需手动指定所有要更新的字段。但仅用于读取场景时无影响。
内容的提问来源于stack exchange,提问作者user1044169
相关产品推荐
相关产品推荐

