76 votes

Puis-je obtenir plus de 1000 enregistrements d'un DirectorySearcher dans Asp.Net?

Je viens de remarquer que la liste des résultats renvoyés est limitée à 1 000. J'ai plus de 1 000 groupes dans mon domaine (domaine ÉNORME). Comment puis-je obtenir plus de 1000 enregistrements? Puis-je commencer à un disque plus tard? 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?

188voto

Joe Points 60749

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

BTW, vous devez également disposer DirectorySearcher lorsque vous avez fini avec elle

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

La documentation de l'API n'est pas très clair, mais en gros:

  • lorsque vous effectuez une recherche paginée, le SizeLimit est ignoré, et tous les résultats sont retournés comme vous itérer sur les résultats retournés par FindAll. Les résultats seront récupérées à partir du serveur d'une page à la fois. J'ai choisi la valeur de 1000 au-dessus, mais vous pouvez utiliser une valeur plus faible si l'on préfère. Le compromis est: à l'aide d'un petit PageSize sera de retour à chaque page de résultats plus rapidement, mais exigera de plus en plus fréquentes des appels vers le 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, jusqu'à SizeLimit résultats sont renvoyées.

Comme Biri l'a souligné, il est important de disposer de SearchResultCollection retourné par FindAll, sinon vous risquez d'avoir une fuite de mémoire, comme décrit dans la section des Remarques de la documentation MSDN pour DirectorySearcher.FindAll: http://msdn.microsoft.com/en-us/library/system.directoryservices.directorysearcher.findall.aspx

Une façon d'aider à éviter cela .NET 2.0 ou version ultérieure est d'écrire un wrapper méthode qui automatiquement dispose la SearchResultCollection. Cela pourrait ressembler à quelque chose comme ce qui suit (ou pourrait être une méthode d'extension .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(DirectorySearcher srch = new DirectorySearcher(dirEnt, "(objectClass=Group)", loadProps))
{
    srch.PageSize = 1000;
    var results = SafeFindAll(srch);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X