Search code examples
c#.net-coremicrosoft-graph-apimicrosoft-graph-sdks

Microsoft Graph client - retrieve more than 15 users?


I'm using Microsoft Graph client and want to retrieve users based on a list of objectIds. So far I've managed to do it like this:

// Create filterstring based on objectId string list.
var filterString = string.Join(" or ", objectIds.Where(x => !string.IsNullOrEmpty(x)).Select(objectId => $"id eq '{objectId}'"));

// Get users by filter
var users = await _graphServiceClient.Users.Request()
               .Select(x => new { x.UserPrincipalName, x.Id })
               .Filter(filterString)
               .GetAsync(ct).ConfigureAwait(false);

But I've hit this error here:

Too many child clauses specified in search filter expression containing 'OR' operators: 22. Max allowed: 15.

Is there another way to only get a portion of users? Or do I need to "chunk" the list up in 15 each?


Solution

  • You should probably split your query and send a BATCH request to the Graph API. This will send only 1 request to the server, but allow you to query for more data at once.

    https://learn.microsoft.com/en-us/graph/sdks/batch-requests?tabs=csharp

    This could look something like this: (untested code)

    var objectIds = new string[0];
    var batchRequestContent = new BatchRequestContent();
    var requestList = new List<string>();
    
    for (var i = 0; i < objectIds.Count(); i += 15)
    {
        var batchObjectIds = objectIds.Where(x => !string.IsNullOrEmpty(x)).Skip(i).Take(15);
        var filterString = string.Join(" or ", batchObjectIds.Select(objectId => $"id eq '{objectId}'"));
    
        var request = _graphServiceClient.Users.Request()
            .Select(x => new { x.UserPrincipalName, x.Id })
            .Filter(filterString);
    
        var requestId = batchRequestContent.AddBatchRequestStep(request);
        requestList.Add(requestId);
    }
    
    var batchResponse = await _graphServiceClient.Batch.Request().PostAsync(batchRequestContent);
    
    var allUsers = new List<User>();
    
    foreach (var it in requestList)
    {
        var users = await batchResponse.GetResponseByIdAsync<GraphServiceUsersCollectionResponse>(it);
    
        allUsers.AddRange(users.Value.CurrentPage);
    }