1

を使用して 1000 またはすべての結果を取得するコードがありますDirectorySearcher

しかし、6000 件の結果のうち 2000 件だけを取得したいのです。

ここに6000の結果を得るコードがありますが、私は2000だけが欲しいです

mySearcher.SizeLimit = 2000;
mySearcher.PageSize = 1000;

SearchResultCollection results = mySearcher.FindAll();

int totalUsers = results.Count;

助けてください。

ありがとう

私の調査によると、PageSize = 0 では 1000 の結果のみが得られ、Pagesize = 1000 ではすべての結果が得られます。

これを機能させるには、さらに助けが必要です。

4

2 に答える 2

2

この投稿によると: DirectorySearcher.FindAll() - PageSize=1000 にする必要があります

SizeLimitこの場合、デフォルトで 1000 件の結果になるサーバー側のデフォルトが使用されているため、これは問題ではありません。このようにページングする必要はありませんでしたが、最小サイズ制限が使用されていると思います(サイズ制限とサーバーサイズ制限の間-自分のADでテストしただけです)。あなたPageSizeは確かにページングですが、バックグラウンドでページングを行い、すべての結果を取得している理由を理解しているので、最終ストリームのみを返します。

あなたの最も簡単な解決策は、これに加えてLinqを使用し、.Take(2000)結果を実行することだと思います。これにより、追加の帯域幅とサーバーでの処理を犠牲にして、目的の結果が得られます.

本当にそれを並べ替えたい場合は、サーバーのデフォルトのページングサイズを更新して大きくする必要があると思います(ただし、これが管理上の理由で実行可能かどうかは疑問です).

編集:

これを大まかに行う方法を次に示します (LinqPad からの簡単に動作するサンプル コード - 式から for ループを取り出してこれを行う方法とは異なり、実際にはすべてを引き継いでいることに注意してください)。

using(DirectoryEntry de = new DirectoryEntry("LDAP://domain.local/dc=domain,dc=local", "user", "password"))
using(DirectorySearcher ds = new DirectorySearcher(de))
{
    ds.Filter="(&(objectCategory=user)(objectClass=user))";
    ds.PageSize= 1000;
    ds.PropertiesToLoad.Clear();
    ds.PropertiesToLoad.Add("objectGuid");

    var results = ds.FindAll();
    var searchResults = results.Cast<System.DirectoryServices.SearchResult>().ToArray();
    int myDesiredPageSize = 2000;

    var upns = new StringCollection();

    for(var step=0; step < Math.Ceiling((double)results.Count / myDesiredPageSize); step++)
    {
        Parallel.ForEach(searchResults.Skip(step*myDesiredPageSize).Take(myDesiredPageSize), result => {
        using(var entry = result.GetDirectoryEntry())
        {
            entry.RefreshCache(new[]{ "userPrincipalName" });

            if(entry.Properties.Contains("userPrincipalName"))
                upns.Add(entry.Properties["userPrincipalName"][0] as string);
        }
        });
    }

    upns.Count.Dump();
}

これにより、私のテスト シナリオでは、LAN 接続を介して約 3 秒で約 1400 の結果が返されます。並行してクエリを実行しているため、より大きな数値は線形にスケーリングされません。また、これは容赦なくADに打撃を与えるため、ある程度並列化を含めることをお勧めします:)

私の通常の操作ではWhenChanged、AD オブジェクトの属性を使用したキャッシュを使用して、実際のクエリを変更されたオブジェクトのみに削減し、同じものを何度もロードするのではなく、最初のヒットのみを取得し、その後の結果を数分の 1 秒に短縮します。このアプローチを使用すると、ページングを完全に廃止し、開始時にプロパティをロードするだけで、変更されたエントリのみをプルすることができます。

于 2012-06-01T15:41:29.443 に答える
2

プロパティには少し奇妙な動作があるようです。 に設定してください。動作しますか?PageSize
0

ところで:
c# Active Directory Services findAll() は 1000 エントリしか返さない

Asp.Net の DirectorySearcher から 1000 を超えるレコードを取得できますか?

于 2012-06-01T15:34:20.533 に答える