Reputation: 1667
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?
Upvotes: 1
Views: 1876
Reputation: 2835
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);
}
Upvotes: 3