web-dev-qa-db-fra.com

Puis-je obtenir plus de 1000 enregistrements d'un DirectorySearcher?

Je viens de remarquer que la liste de retour des résultats est limitée à 1000. J'ai plus de 1000 groupes dans mon domaine (domaine HUGE). Comment puis-je obtenir plus de 1000 enregistrements? Puis-je commencer par un enregistrement ultérieur? Puis-je le découper en plusieurs recherches?

Voici ma requête:

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();

J'ai essayé de définir srch.SizeLimit = 2000;, mais cela ne semble pas fonctionner. Des idées?

68
naspinski

Vous devez définir DirectorySearcher.PageSize sur une valeur non nulle pour obtenir tous les résultats.

BTW vous devez également disposer DirectorySearcher lorsque vous avez terminé avec elle

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

La documentation de l'API n'est pas très claire, mais essentiellement:

  • lorsque vous effectuez une recherche paginée, SizeLimit est ignoré et tous les résultats correspondants sont renvoyés lorsque vous parcourez les résultats renvoyés par FindAll. Les résultats seront récupérés du serveur une page à la fois. J'ai choisi la valeur de 1000 ci-dessus, mais vous pouvez utiliser une valeur plus petite si vous préférez. Le compromis est le suivant: l'utilisation d'un petit PageSize retournera chaque page de résultats plus rapidement, mais nécessitera des appels plus fréquents au serveur lors de l'itération sur un grand nombre de résultats.

  • par défaut, la recherche n'est pas paginée (PageSize = 0). Dans ce cas, les résultats jusqu'à SizeLimit sont renvoyés.

Comme l'a souligné Biri, il est important de supprimer le SearchResultCollection renvoyé par FindAll, sinon vous risquez d'avoir une fuite de mémoire comme décrit dans la section Remarques de la documentation MSDN pour DirectorySearcher.FindAll .

Une façon d'éviter cela dans .NET 2.0 ou version ultérieure consiste à écrire une méthode wrapper qui supprime automatiquement SearchResultCollection. Cela pourrait ressembler à ce qui suit (ou pourrait être une méthode d'extension dans .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
}

Vous pouvez ensuite l'utiliser comme suit:

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