SharePoint文档库唯一权限计数:算法正确性与效率咨询
问题分析与解决方案
当前算法的问题
你的代码统计的是所有非继承权限条目的总数,而非SharePoint文档库要求的「唯一权限主体(用户/组)数量」,这就是实际只有3个共享却得到22结果的核心原因:
- 同一用户/组如果在多个子项(文件夹、文件)上被单独分配权限,会被重复计数
- 递归遍历所有子项时,每个带唯一权限的子项的权限条目都会被累加,完全没有去重逻辑
另外,递归遍历所有子项的方式在文档库文件数量大时会有严重性能问题,频繁调用Graph API容易触发速率限制,绝非最优实现。
正确的统计逻辑
要统计的是所有被分配了唯一权限的独特用户/组数量,核心是:
- 收集所有权限条目中的主体ID(用户ID或组ID)
- 对这些ID做去重处理,最终去重后的数量就是唯一权限的真实总数
优化后的实现示例
private static async Task<int> GetUniquePermissionPrincipalsCount(GraphServiceClient graphClient, string driveId, string itemId, HashSet<string> uniquePrincipals = null) { // 初始化去重集合,自动忽略重复ID uniquePrincipals ??= new HashSet<string>(); // 获取当前项的非继承权限 var permissions = await graphClient.Drives[driveId].Items[itemId].Permissions.Request().GetAsync(); var directPermissions = permissions.Where(p => p.InheritedFrom == null); // 提取权限主体ID并加入去重集合 foreach (var perm in directPermissions) { // 处理用户权限 if (!string.IsNullOrEmpty(perm.GrantedTo?.User?.Id)) { uniquePrincipals.Add(perm.GrantedTo.User.Id); } // 处理组权限 else if (!string.IsNullOrEmpty(perm.GrantedTo?.Group?.Id)) { uniquePrincipals.Add(perm.GrantedTo.Group.Id); } // 处理外部用户等特殊权限主体 else if (perm.GrantedToIdentitiesV2?.Any() == true) { uniquePrincipals.Add(perm.GrantedToIdentitiesV2.First().Id); } } // 递归处理子项 var children = await graphClient.Drives[driveId].Items[itemId].Children.Request().GetAsync(); if (children != null) { foreach (var child in children) { await GetUniquePermissionPrincipalsCount(graphClient, driveId, child.Id, uniquePrincipals); } } return uniquePrincipals.Count; }
更高效的最优方案
递归遍历所有子项的方式在大型文档库中效率极低,建议改用以下思路:
- 先查询文档库中所有拥有唯一权限的项(通过筛选
HasUniqueRoleAssignments = true) - 批量获取这些项的权限,统一提取主体ID并去重
- 这种方式大幅减少API调用次数,避免递归带来的性能瓶颈
内容的提问来源于stack exchange,提问作者Phil Salomon
相关产品推荐
相关产品推荐

