我正在尝试提高对活动目录层次结构组结构的searcher.FindAll()调用的性能。
该代码获取所有用户组的SearchResultCollection,然后过滤搜索字符串上的组。 SearchResultCollection集合中有大约400个组,过滤下来的版本通常为40个。在迭代调用期间,我看不到内置缓存没有任何好处(DirectorySearcher.CacheResults = True)。
例如,如果我连续20次调用以下代码,则执行时间几乎相同。
下面的代码每次执行时,对SearchResult的所有400次迭代都会受到相同的惩罚。
string groupFilter = "ExampleFilter";
DirectoryEntry root = GetRootDirectoryEntry();
string userPath = GetUserPath(username, root);
var searcher = new DirectorySearcher(root)
{
SearchScope = SearchScope.Subtree,
Filter = string.Format("(member:XXXX:={0})", userPath) + ""
//Any wildcard based search for distinguishedname like below returns no results, which is incorrect
//Filter = string.Format("(& (member:XXXX:={0}) (distinguishedname=*{1}) )", userPath, groupFilter)
};
searcher.PropertiesToLoad.Add("Name");
searcher.PropertiesToLoad.Add("distinguishedname");
var groupResults = searcher.FindAll();
var allFilteredGroups = new HashSet<string>();
foreach (SearchResult gr in groupResults) //approx 400 in the groupResults, same time penalty for every iteration, every time
{
var isRelevant = gr.Path.Contains(groupFilter);
if (isRelevant)
{
//Do Stuff
allFilteredGroups.Add(value);
}
}
return allFilteredGroups.ToList(); //approx 40
为什么缓存不提供任何改进?关于如何减少我不希望重复的所有这些组的任何建议?
我假设您正在尝试仅包括来自特定OU的组?
您是正确的,不能使用部分distinguishedName
进行过滤。但是,通过修改传递给SearchRoot
的DirectorySearcher
,只能在一个特定的OU中搜索。例如:
DirectoryEntry root = new DirectoryEntry("LDAP://OU=MyGroups,DC=example,DC=com");
DirectoryEntry
指向MyGroups
OU。因此,如果将其传递给DirectorySearcher
,则它将仅在该OU中搜索。
如果您不希望它搜索子OU,也可以将SearchScope
设置为OneLevel
。 Subtree
是默认设置,因此,如果您要这样做,则完全不需要设置。
即使您想在多个OU中查找组,最好还是对每个所需的OU重复搜索,而不是要求所有内容并丢弃大部分结果。