You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 16:37:12