Получить записи из Active Directory, используя алгоритм структуры данных в C # - PullRequest
0 голосов
/ 26 ноября 2018

Мне нужно получить записи активного каталога и вставить в базу данных SQL.Есть около 10000 записей.Я использовал этот код:

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 выглядит аналогично двоичному дереву.

1 Ответ

0 голосов
/ 26 ноября 2018

Список, возвращаемый DirectorySearcher.FindAll(), является просто списком.Таким образом, вы не можете пройти его лучше, чем уже есть.

Чтобы оптимизировать это, не используйте GetDirectoryEntry().Это делает две вещи:

  1. Создание другого сетевого запроса к AD, который не нужен, так как поиск может вернуть любые атрибуты, которые вы хотите, и
  2. Извлечение памяти, так как все эти DirectoryEntryобъекты будут оставаться в памяти до тех пор, пока вы не вызовете Dispose() или GC не успеет запустить (чего не произойдет, пока ваш цикл не закончится).

Сначала добавьте displayName к вашему PropertiesToLoad чтобы убедиться, что возвращается тоже.Затем вы можете получить доступ к каждому свойству, используя result.Properties[propertyName][0].При таком способе каждое свойство возвращается в виде массива, даже если это атрибут с одним значением в AD, поэтому вам потребуется [0].

Кроме того, если ваше приложениеоставаясь открытым после завершения этого поиска, обязательно наберите Dispose() на SearchResultCollection, полученном из FindAll().В документации к FindAll(), раздел «Замечания» указывает, что в противном случае возможна утечка памяти.Или вы можете просто поместить его в 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);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...