1. ホーム
  2. c#

DirectorySearcherから1000件以上のレコードを取得することはできますか?

2023-09-18 19:22:28

質問

結果のリターンのリストが 1000 に制限されていることに気づきました。私のドメイン (HUGE ドメイン) には 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 としました。 を設定してみましたが、うまくいかないようです。何かアイデアはありますか?

どのように解決するのですか?

すべての結果を取得するためには、DirectorySearcher.PageSizeに0以外の値を設定する必要があります。

ちなみに、DirectorySearcherを使用し終わったら、Disposeする必要があります。

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

APIドキュメントがあまり明確ではありませんが、基本的には

  • ページ検索を行う場合、SizeLimit は無視され、FindAll によって返される結果を繰り返しながら、一致するすべての結果が返されます。 結果はサーバーから一度に1ページずつ取得されます。 私は上記の1000という値を選びましたが、お好みでもっと小さな値を使うこともできます。 トレードオフは、小さなPageSizeを使用すると、結果の各ページをより速く返しますが、多数の結果を反復処理する際にサーバーへの呼び出しがより頻繁に必要になることです。

  • は、デフォルトでは、検索はページングされません (PageSize = 0)。 この場合、SizeLimitまでの結果が返されます。

Biriさんが指摘されているように、FindAllが返すSearchResultCollectionをdisposeすることが重要で、そうしないとメモリリークが発生する可能性があります。 の MSDN ドキュメントの「備考」セクションで説明されているように、DirectorySearcher.FindAll の .

.NET 2.0以降でこれを回避するのに役立つ1つの方法は、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);
}