我需要获取活动目录记录并插入SQL数据库中。大约有10,000条记录。我使用了以下代码:
List<ADUser> users = new List<ADUser>();
DirectoryEntry entry = new DirectoryEntry("LDAP://xyz.com");
ADUser userToAdd = null;
IList<string> dict = new List<string>();
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(&(objectClass=user))";
search.PropertiesToLoad.Add("samaccountname");
search.PageSize = 1000;
foreach (SearchResult result in search.FindAll())
{
DirectoryEntry user = result.GetDirectoryEntry();
if (user != null && user.Properties["displayName"].Value!=null)
{
userToAdd = new ADUser
{
FullName = Convert.ToString(user.Properties["displayName"].Value),
LanId = Convert.ToString(user.Properties["sAMAccountName"].Value)
};
users.Add(userToAdd);
}
}
如何在速度和空间复杂度方面优化上述代码?我可以在二叉树中使用遍历,因为Active Directory结构看起来类似于二叉树。
答案 0 :(得分:0)
DirectorySearcher.FindAll()
返回的列表只是一个列表。因此,您无法比以前更好地遍历它。
要对此进行优化,请不要使用GetDirectoryEntry()
。这是在做两件事:
DirectoryEntry
对象将保留在内存中,直到您调用Dispose()
或GC有时间运行(直到循环最终结束为止)。首先,将displayName
添加到您的PropertiesToLoad
中,以确保也将其返回。然后,您可以使用result.Properties[propertyName][0]
访问每个属性。通过这种方式,每个属性都作为数组返回,即使它是AD中的单值属性,因此也需要[0]
。
此外,如果此搜索完成后您的应用仍处于打开状态,请确保您从Dispose()
出来的SearchResultCollection
上调用FindAll()
。在FindAll()
的文档中,the "Remarks" section表示如果没有,可能会发生内存泄漏。或者,您可以将其放在using
块中:
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(&(objectClass=user))";
search.PropertiesToLoad.Add("sAMAccountName");
search.PropertiesToLoad.Add("displayName");
search.PageSize = 1000;
using (SearchResultCollection results = search.FindAll()) {
foreach (SearchResult result in results) {
if (result.Properties["displayName"][0] != null) {
userToAdd = new ADUser {
FullName = (string) result.Properties["displayName"][0],
LanId = (string) result.Properties["sAMAccountName"][0]
};
users.Add(userToAdd);
}
}
}