Microsoft Graph分页迭代器(异步与同步的Lambda函数)

后端开发 2026-07-12

有人知道在下面这段代码中,在PageIterator的 lambda函数里,为什么会收到如下错误:

Cannot implicitly convert type 'bool' to 'System.Threading.Tasks.Task<bool>'
   public async Task<IEnumerable<EmployeeViewModel>> GetMembersOf(GroupQueryViewModel model) 
   {
       var graphClient = await GetGraphClient();
       var filter = GetFilterQuery(model);

       var groups = await graphClient.Groups.GetAsync(requestConfiguration =>
       {
           requestConfiguration.QueryParameters.Filter = filter;
           requestConfiguration.QueryParameters.Select = ["id"];
       });

       var groupIds = new List<string>();
       var pageIterator = PageIterator<Group, GroupCollectionResponse>.CreatePageIterator(
           graphClient,
           groups,
           (group) =>
           {
               groupIds.Add(group.Id);
               return true;
           },
           (req) =>
           {
               return req;
           });

       await pageIterator.IterateAsync();

       ConcurrentDictionary<string, EmployeeViewModel> allMembers = new ConcurrentDictionary<string, EmployeeViewModel>();
       Parallel.ForEachAsync(groupIds, async (id, cancellationToken) =>
       {
           var members = await graphClient.Groups[id].Members.GetAsync(requestConfiguration =>
           {
               requestConfiguration.QueryParameters.Select = [   
                   "userPrincipalName", "displayName", "mail",
                   "givenName", "surname", "photo"
               ];
           });

           var iterator = PageIterator<User, UserCollectionResponse>.CreatePageIterator(
               graphClient,
               members,
               (user) =>
               {
                   if (allMembers.ContainsKey(user.Id))
                       return true;
                   var nameParts = user.UserPrincipalName.Split('@');
                   EmployeeViewModel employee = new EmployeeViewModel
                   {
                      /* Creation logic */
                   };
                   allMembers.TryAdd(user.Id, employee);
                   return true;
               },
               (req) =>
               {
                   return req;
               });
           await iterator.IterateAsync();
       });

       return allMembers.Values;
   }

我似乎找不到解决办法。
PageIterator正确地指出它期望的是一个Function
在lambda内没有async/ await调用,因此我不明白为什么它期望返回值是Task。

我尝试了这个:

async (user) => 
{
    /* Same logic */
}

但这同样有问题,会产生编译错误。
有没有人知道我该怎么做才能修复?
我猜这与它运行的上下文有关,但我说不清具体原因。
因为针对Groups的第一个PageIterator能正常工作,我唯一的猜测是它来自foreach语句内部的执行。
我尝试将

Parallel.ForEach(...)

替换为

foreach(...)

但结果仍然一样。

解决方案

问题在于 graphClient.Groups[id].Members.GetAsync 返回的是 DirectoryObjectCollectionResponse,而你的页面迭代器期望的是 UserCollectionResponse

你可以对成员进行类型转换,只返回属于某个组的用户。

使用 graphClient.Groups[id].Members.GraphUser.GetAsync

var members = await graphClient.Groups[id].Members.GraphUser.GetAsync(requestConfiguration =>
           {
               requestConfiguration.QueryParameters.Select = [   
                   "userPrincipalName", "displayName", "mail",
                   "givenName", "surname"
               ];
           });

           var iterator = PageIterator<User, UserCollectionResponse>.CreatePageIterator(
               graphClient,
               members,
               (user) =>
               {
                   if (allMembers.ContainsKey(user.Id))
                       return true;
                   var nameParts = user.UserPrincipalName.Split('@');
                   EmployeeViewModel employee = new EmployeeViewModel
                   {
                      /* Creation logic */
                   };
                   allMembers.TryAdd(user.Id, employee);
                   return true;
               },
               (req) =>
               {
                   return req;
               });
           await iterator.IterateAsync();

还有一点需要注意……你不能为多名用户返回照片。你一次只能为一个用户获取照片。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章