从 DirectorySearcher 获取 6000 条记录中的 2000 条

本文关键字:2000 记录 获取 6000 DirectorySearcher | 更新日期: 2023-09-27 18:35:57

我有一个代码,它要么得到 1000 个,要么使用 DirectorySearcher 获得所有结果。

但我只想得到 2000 个结果中的 6000 个。

这是获得 6000 个结果的代码,而我只想要 2000 个结果

mySearcher.SizeLimit = 2000;
mySearcher.PageSize = 1000;
SearchResultCollection results = mySearcher.FindAll();
int totalUsers = results.Count;

请帮忙。

谢谢

我的研究表明,PageSize = 0 只给出 1000 个结果,Pagesize = 1000 给出所有结果。

需要更多帮助才能完成这项工作。

从 DirectorySearcher 获取 6000 条记录中的 2000 条

PageSize属性似乎有轻微的奇怪行为。
请将其设置为 0 ,这有效吗?

顺便一提:
c# Active Directory Services findAll() 仅返回 1000 个条目

我可以在 Asp.Net 中从目录搜索器获取超过 1000 条记录吗?

根据这篇文章: DirectorySearcher.FindAll() - 应该有 PageSize=1000

在这种情况下SizeLimit无关紧要,因为使用的是服务器端默认值,默认为 1000 个结果。我从不需要像这样分页,但我想使用了最小大小限制(在您的大小限制和服务器大小限制之间 - 刚刚在我自己的 AD 中对其进行了测试)。您的PageSize确实是分页,但是它在后台进行分页,并且仅返回最终流,据我所知,这就是您获得所有结果的原因。

我相信您最简单的解决方案是在此基础上使用 Linq 并对结果进行.Take(2000)。这将以额外的带宽和服务器上的处理为代价获得您想要的结果。

如果您真的想对其进行排序,我想您将不得不将服务器默认分页大小更新为更高(尽管出于管理原因我怀疑这是否可行)。

编辑:

以下是我大致执行此操作的方法(来自我的 LinqPad 的快速工作示例代码 - 另请注意,我实际上带来了所有内容,这与您可能希望通过将 for 循环从等式中取出来执行此操作的方式不同):

using(DirectoryEntry de = new DirectoryEntry("LDAP://domain.local/dc=domain,dc=local", "user", "password"))
using(DirectorySearcher ds = new DirectorySearcher(de))
{
    ds.Filter="(&(objectCategory=user)(objectClass=user))";
    ds.PageSize= 1000;
    ds.PropertiesToLoad.Clear();
    ds.PropertiesToLoad.Add("objectGuid");
    var results = ds.FindAll();
    var searchResults = results.Cast<System.DirectoryServices.SearchResult>().ToArray();
    int myDesiredPageSize = 2000;
    var upns = new StringCollection();
    for(var step=0; step < Math.Ceiling((double)results.Count / myDesiredPageSize); step++)
    {
        Parallel.ForEach(searchResults.Skip(step*myDesiredPageSize).Take(myDesiredPageSize), result => {
        using(var entry = result.GetDirectoryEntry())
        {
            entry.RefreshCache(new[]{ "userPrincipalName" });
            if(entry.Properties.Contains("userPrincipalName"))
                upns.Add(entry.Properties["userPrincipalName"][0] as string);
        }
        });
    }
    upns.Count.Dump();
}

在我的测试场景中,这在我的 lan 连接中大约 3 秒内返回大约 1400 个结果。由于我们是并行查询的,因此较高的数字不应线性扩展。此外,您可能希望在一定程度上包含并行化,因为这会无情地锤击 AD :)

在我的正常操作中,我使用带有 AD 对象属性WhenChanged缓存来减少我的实际查询,以仅更改的对象,而不是一遍又一遍地加载相同的东西,这只在第一次受到打击,随后的结果是几分之一秒。采用这种方法,您可以完全取消分页,只需在启动时加载属性,然后仅提取更改的条目(如果这是一个选项)。