Могу ли я получить более 1000 записей из DirectorySearcher? - PullRequest
67 голосов
/ 18 сентября 2008

Я только что заметил, что список возвращаемых результатов ограничен 1000. У меня более 1000 групп в моем домене (ОГРОМНЫЙ домен). Как я могу получить более 1000 записей? Могу ли я начать с более поздней записи? Можно ли разделить его на несколько поисков?

Вот мой запрос:

DirectoryEntry dirEnt = new DirectoryEntry("LDAP://dhuba1kwtn004");
string[] loadProps = new string[] { "cn", "samaccountname", "name", "distinguishedname" };
DirectorySearcher srch = new DirectorySearcher(dirEnt, "(objectClass=Group)", loadProps);
var results = srch.FindAll();

Я попытался установить srch.SizeLimit = 2000; , но, похоже, это не работает. Есть идеи?

1 Ответ

169 голосов
/ 18 сентября 2008

Вам нужно установить DirectorySearcher.PageSize в ненулевое значение, чтобы получить все результаты.

Кстати, вы также должны избавиться от DirectorySearcher, когда закончите с ним

using(var srch = new DirectorySearcher(dirEnt, "(objectClass=Group)", loadProps))
{
    srch.PageSize = 1000;
    var results = srch.FindAll();
}

Документация по API не очень понятна, но по существу:

  • когда вы выполняете постраничный поиск, SizeLimit игнорируется, и все совпадающие результаты возвращаются, когда вы перебираете результаты, возвращаемые FindAll. Результаты будут получены с сервера страницу за раз. Я выбрал значение 1000 выше, но вы можете использовать меньшее значение, если хотите. Компромисс: использование небольшого PageSize вернет каждую страницу результатов быстрее, но потребует более частых обращений к серверу при переборе большого количества результатов.

  • по умолчанию поиск не разбит на страницы (PageSize = 0). В этом случае возвращается результат до SizeLimit.

Как указал Бири, важно утилизировать SearchResultCollection, возвращаемую FindAll, в противном случае может возникнуть утечка памяти , как описано в разделе «Примечания» документации MSDN для DirectorySearcher.FindAll .

Один из способов избежать этого в .NET 2.0 или более поздней версии - написать метод-обертку, который автоматически удаляет SearchResultCollection. Это может выглядеть примерно так (или может быть методом расширения в .NET 3.5):

public IEnumerable<SearchResult> SafeFindAll(DirectorySearcher searcher)
{
    using(SearchResultCollection results = searcher.FindAll())
    {
        foreach (SearchResult result in results)
        {
            yield return result;        
        } 
    } // SearchResultCollection will be disposed here
}

Вы можете использовать это следующим образом:

using(var srch = new DirectorySearcher(dirEnt, "(objectClass=Group)", loadProps))
{
    srch.PageSize = 1000;
    var results = SafeFindAll(srch);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...