In Windows Azure Graph API, some operations on groups are transitive and others are scoped only to direct members of the group. So if you have a user that is a member of developers group, and groups reporting and admin contain developers, non-transitive operation will not tell you that your user is member of reporting.

I needed to get all group names that user is assigned to. I had the following code:

IUserFetcher userFetcher = graphClient.Users.GetByObjectId(userObjectId);
IPagedCollection<IDirectoryObject> pagedCollection = await userFetcher.MemberOf.ExecuteAsync();
// further processing

I was all nice until nested groups appeared. MemberOf is not transitive, so I needed something else. According to documentation, I can do something like:

var groupIds = await userFetcher.GetMemberGroupsAsync(false);

but that gave me a collection of objectIds and not the rich object. I needed to query Graph API for list of Group objects that I am interested in, not falling into n+1 trap using graphClient.Groups.GetByObjectId(). Note that graphClient.Groups.Where() clause is limited solely to displayName startsWith filter and every other interesting predicate will throw an exception.

I know about batches but still, some filtering would be an obvious choice.

Finally, after hours of experimenting and googling, I found GetObjectsByObjectIdsAsync method of ActiveDirectoryClient itself. Now the following code works:

IUserFetcher userFetcher = graphClient.Users.GetByObjectId(userObjectId);
IEnumerable<string> userGroupIds = await userFetcher.GetMemberGroupsAsync(false);
List<string> userGroupIdList = userGroupIds.ToList();
IEnumerable<IDirectoryObject> userGroups = await graphClient.GetObjectsByObjectIdsAsync(userGroupIdList, new List<string> {"group"});
foreach (IDirectoryObject directoryObject in userGroups)
{
    var group = directoryObject as Group;
    if (group != null)
    {
        groupNames.Add(group.DisplayName);
    }
}

Hope it will help someone in a similar situation. This is a horrible developer experience and I am seriously considering contributing to Graph project since all pieces seem to exist, someone just need to put them in a correct place.