我有一个代码,使用DirectorySearcher
得到1000或所有结果。
但我想得到6000个结果中的2000个。
这是获得6000个结果的代码,而我只想要2000
mySearcher.SizeLimit = 2000;
mySearcher.PageSize = 1000;
SearchResultCollection results = mySearcher.FindAll();
int totalUsers = results.Count;
请帮忙。
由于
我的研究表明,PageSize = 0仅提供1000个结果,而Pagesize = 1000则给出所有结果。
需要更多帮助才能完成这项工作。
答案 0 :(得分:2)
PageSize
属性似乎有一个slight奇怪的behavior。
请将其设置为0
,这有效吗?
顺便说一下:
c# Active Directory Services findAll() returns only 1000 entries
Can I get more than 1000 records from a DirectorySearcher in Asp.Net?
答案 1 :(得分:2)
根据这篇文章:DirectorySearcher.FindAll() - should have PageSize=1000
SizeLimit
无关紧要在这种情况下,因为正在使用服务器端默认值,默认为1000个结果。我从来不需要这样的页面,但我想使用了最小大小限制(在您的大小限制和服务器大小限制之间 - 只在我自己的AD中测试它)。你的PageSize
确实是分页,但是它在后台进行分页,只返回最后一个流,因为我明白这就是你得到所有结果的原因。
我相信您最简单的解决方案就是在此基础上使用Linq并对结果进行.Take(2000)
。这将以您在服务器上的额外带宽和处理成本为您获得所需的结果。
如果你真的想对它进行排序,我猜你必须更新服务器的默认分页大小要更高(尽管我怀疑这是出于行政原因这是可行的)。
编辑:
以下是我如何粗略地解决这个问题(来自我的LinqPad的快速工作示例代码 - 同时注意到我实际上带来了所有内容,而不是通过取出等式中的for循环来实现这一点):< / p>
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();
}
在我的测试场景中,我的局域网连接在大约3秒内返回大约1400个结果。由于我们并行查询,因此较高的数字不应线性扩展。此外,您可能希望在某种程度上包含并行化,因为这将无情地锤击AD:)
在我的正常操作中,我使用AD对象的WhenChanged
属性进行缓存,以将我的实际查询减少到仅更改的对象,而不是一遍又一遍地加载相同的东西,这只会在第一次触及后续结果是一秒钟的一小部分。采用这种方法,您可以完全取消分页,只需在启动时加载属性,然后只选择已更改的条目(如果这是一个选项)。