在 C# 中使用数据结构算法从 Active Directory 中检索记录
Retrieve records from Active Directory using data structure algorithm in c#
我需要获取活动目录记录并插入 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);
}
}
如何在速度和 space 复杂性方面优化上述代码?我可以在二叉树中使用遍历吗,因为 Active Directory 结构看起来类似于二叉树。
由 DirectorySearcher.FindAll()
编辑的列表 return 只是一个列表。所以你不能比现在更好地穿越它了。
要对此进行优化,请不要使用 GetDirectoryEntry()
。那就是做两件事:
- 向 AD 发出另一个不必要的网络请求,因为搜索可以 return 您想要的任何属性,并且
- 占用内存,因为所有这些
DirectoryEntry
对象将保留在内存中,直到您调用 Dispose()
或 GC 有时间 运行 (它不会直到您的循环最终结束)。
首先,将 displayName
添加到您的 PropertiesToLoad
以确保它也得到 returned。然后您可以使用 result.Properties[propertyName][0]
访问每个 属性。以这种方式使用,every 属性 被 returned 作为一个数组,即使它是 AD 中的单值属性,因此你需要 [0]
.
此外,如果您的应用程序在此搜索完成后仍保持打开状态,请确保在 FindAll()
出现的 SearchResultCollection
上调用 Dispose()
。在 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);
}
}
}
我需要获取活动目录记录并插入 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);
}
}
如何在速度和 space 复杂性方面优化上述代码?我可以在二叉树中使用遍历吗,因为 Active Directory 结构看起来类似于二叉树。
由 DirectorySearcher.FindAll()
编辑的列表 return 只是一个列表。所以你不能比现在更好地穿越它了。
要对此进行优化,请不要使用 GetDirectoryEntry()
。那就是做两件事:
- 向 AD 发出另一个不必要的网络请求,因为搜索可以 return 您想要的任何属性,并且
- 占用内存,因为所有这些
DirectoryEntry
对象将保留在内存中,直到您调用Dispose()
或 GC 有时间 运行 (它不会直到您的循环最终结束)。
首先,将 displayName
添加到您的 PropertiesToLoad
以确保它也得到 returned。然后您可以使用 result.Properties[propertyName][0]
访问每个 属性。以这种方式使用,every 属性 被 returned 作为一个数组,即使它是 AD 中的单值属性,因此你需要 [0]
.
此外,如果您的应用程序在此搜索完成后仍保持打开状态,请确保在 FindAll()
出现的 SearchResultCollection
上调用 Dispose()
。在 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);
}
}
}