在 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()。那就是做两件事:

  1. 向 AD 发出另一个不必要的网络请求,因为搜索可以 return 您想要的任何属性,并且
  2. 占用内存,因为所有这些 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);
        }
    }
}