[C#] DirectorySearcherのPropertiesToLoadの使い方

DirectorySearcherPropertiesToLoadは、Active Directoryから取得する属性を指定するためのプロパティです。

デフォルトでは、すべての属性が取得されますが、PropertiesToLoadを使用すると、必要な属性だけを取得するように制限できます。

これにより、検索結果のパフォーマンスが向上し、不要なデータの取得を避けることができます。

使用方法としては、DirectorySearcherオブジェクトのPropertiesToLoadプロパティに属性名を文字列として追加します。

例えば、searcher.PropertiesToLoad.Add("cn")とすることで、共通名(cn)属性のみを取得します。

この記事でわかること
  • PropertiesToLoadの基本的な使い方
  • ユーザーやグループ情報の取得方法
  • 検索結果の効率的な処理手法
  • パフォーマンス向上のためのテクニック
  • フィルタリングを活用した検索方法

目次から探す

PropertiesToLoadの基本

PropertiesToLoadとは

PropertiesToLoadは、C#のDirectorySearcherクラスにおいて、LDAP(Lightweight Directory Access Protocol)検索の際に取得したい属性を指定するためのプロパティです。

これを使用することで、必要な情報だけを効率的に取得することができます。

例えば、ユーザーの名前やメールアドレスなど、特定の属性のみを指定して検索することが可能です。

なぜPropertiesToLoadを使うのか

PropertiesToLoadを使用する主な理由は、以下の通りです。

スクロールできます
理由説明
パフォーマンス向上必要な属性のみを取得することで、検索速度が向上します。
データ転送量の削減不要なデータを取得しないため、ネットワークの負荷が軽減されます。
コードの可読性向上取得する属性を明示的に指定することで、コードが分かりやすくなります。

デフォルトの動作とPropertiesToLoadの違い

DirectorySearcherを使用する際、PropertiesToLoadを指定しない場合、デフォルトで多くの属性が取得されます。

これに対し、PropertiesToLoadを使用することで、必要な属性だけを選択的に取得できます。

  • デフォルトの動作: 多くの属性が取得され、不要なデータも含まれる。
  • PropertiesToLoadを使用した場合: 指定した属性のみが取得され、効率的なデータ処理が可能。

このように、PropertiesToLoadを活用することで、より効率的なLDAP検索が実現できます。

PropertiesToLoadの使い方

PropertiesToLoadの設定方法

PropertiesToLoadを設定するには、DirectorySearcherオブジェクトのPropertiesToLoadプロパティに、取得したい属性名を指定します。

以下はその基本的な設定方法です。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent(); // フォームの初期化
        DirectorySearcher searcher = new DirectorySearcher();
        searcher.PropertiesToLoad.Add("cn"); // Common Nameを追加
        searcher.PropertiesToLoad.Add("mail"); // メールアドレスを追加
    }
}

このコードでは、cn(Common Name)とmail(メールアドレス)の属性を取得するように設定しています。

属性名の指定方法

属性名は、LDAPで定義された属性名を使用します。

一般的な属性名の例を以下に示します。

スクロールできます
属性名説明
cnCommon Name
snSurname(姓)
mailメールアドレス
givenName名(ファーストネーム)
telephoneNumber電話番号

これらの属性名をPropertiesToLoadに追加することで、必要な情報を取得できます。

複数属性の指定

複数の属性を指定する場合は、PropertiesToLoadに対して複数回Addメソッドを呼び出すか、配列を使用して一度に追加することができます。

以下はその例です。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent(); // フォームの初期化
        DirectorySearcher searcher = new DirectorySearcher();
        string[] properties = { "cn", "mail", "sn", "telephoneNumber" };
        
        searcher.PropertiesToLoad.AddRange(properties); // 複数属性を追加
    }
}

このコードでは、cnmailsntelephoneNumberの4つの属性を一度に追加しています。

取得した属性の利用方法

取得した属性は、検索結果からアクセスすることができます。

以下は、検索結果から属性を取得し、表示する例です。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent(); // フォームの初期化
        DirectorySearcher searcher = new DirectorySearcher();
        searcher.PropertiesToLoad.Add("cn");
        searcher.PropertiesToLoad.Add("mail");
        SearchResult result = searcher.FindOne(); // 検索を実行
        if (result != null)
        {
            string commonName = result.Properties["cn"][0].ToString(); // Common Nameを取得
            string email = result.Properties["mail"][0].ToString(); // メールアドレスを取得
            MessageBox.Show($"名前: {commonName}\nメール: {email}"); // 結果を表示
        }
    }
}

このコードでは、検索結果からcnmailの属性を取得し、メッセージボックスで表示しています。

Propertiesコレクションを通じて、指定した属性にアクセスすることができます。

実践例

ユーザー情報の取得

ユーザー情報を取得するためには、DirectorySearcherを使用して、特定のユーザーの属性を検索します。

以下のコードは、ユーザーのcn(Common Name)とmail(メールアドレス)を取得する例です。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent(); // フォームの初期化
        DirectorySearcher searcher = new DirectorySearcher();
        searcher.Filter = "(objectClass=user)"; // ユーザーオブジェクトをフィルタリング
        searcher.PropertiesToLoad.Add("cn"); // Common Nameを追加
        searcher.PropertiesToLoad.Add("mail"); // メールアドレスを追加
        SearchResultCollection results = searcher.FindAll(); // 検索を実行
        foreach (SearchResult result in results)
        {
            string commonName = result.Properties["cn"][0].ToString(); // Common Nameを取得
            string email = result.Properties["mail"][0].ToString(); // メールアドレスを取得
            MessageBox.Show($"ユーザー名: {commonName}\nメール: {email}"); // 結果を表示
        }
    }
}

このコードでは、すべてのユーザーのcnmailを取得し、メッセージボックスで表示しています。

グループ情報の取得

グループ情報を取得する場合も、DirectorySearcherを使用します。

以下のコードは、特定のグループのcn(Common Name)とmember(メンバー)を取得する例です。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent(); // フォームの初期化
        DirectorySearcher searcher = new DirectorySearcher();
        searcher.Filter = "(objectClass=group)"; // グループオブジェクトをフィルタリング
        searcher.PropertiesToLoad.Add("cn"); // Common Nameを追加
        searcher.PropertiesToLoad.Add("member"); // メンバーを追加
        SearchResultCollection results = searcher.FindAll(); // 検索を実行
        foreach (SearchResult result in results)
        {
            string groupName = result.Properties["cn"][0].ToString(); // グループ名を取得
            string[] members = result.Properties["member"].Cast<string>().ToArray(); // メンバーを取得
            MessageBox.Show($"グループ名: {groupName}\nメンバー数: {members.Length}"); // 結果を表示
        }
    }
}

このコードでは、すべてのグループのcnとそのメンバーを取得し、メッセージボックスでグループ名とメンバー数を表示しています。

特定の属性のみを取得する例

特定の属性のみを取得する場合、PropertiesToLoadを使用して必要な属性を指定します。

以下のコードは、ユーザーのgivenName(名)とsn(姓)を取得する例です。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent(); // フォームの初期化
        DirectorySearcher searcher = new DirectorySearcher();
        searcher.Filter = "(objectClass=user)"; // ユーザーオブジェクトをフィルタリング
        searcher.PropertiesToLoad.Add("givenName"); // 名を追加
        searcher.PropertiesToLoad.Add("sn"); // 姓を追加
        SearchResultCollection results = searcher.FindAll(); // 検索を実行
        foreach (SearchResult result in results)
        {
            string firstName = result.Properties["givenName"][0].ToString(); // 名を取得
            string lastName = result.Properties["sn"][0].ToString(); // 姓を取得
            MessageBox.Show($"名: {firstName}\n姓: {lastName}"); // 結果を表示
        }
    }
}

このコードでは、すべてのユーザーのgivenNamesnを取得し、メッセージボックスで表示しています。

特定の属性のみを取得することで、必要な情報を効率的に扱うことができます。

パフォーマンスの最適化

PropertiesToLoadによるパフォーマンス向上

PropertiesToLoadを使用することで、LDAP検索のパフォーマンスを向上させることができます。

デフォルトでは、DirectorySearcherは多くの属性を取得しますが、必要な属性だけを指定することで、検索処理が軽くなります。

これにより、以下のような利点があります。

  • 検索速度の向上: 不要な属性を取得しないため、検索処理が迅速になります。
  • リソースの節約: サーバーやクライアントのメモリ使用量が減少し、全体的なリソースの消費が抑えられます。

不要なデータ取得の回避

PropertiesToLoadを適切に設定することで、不要なデータの取得を回避できます。

これにより、以下のような効果が得られます。

  • ネットワーク負荷の軽減: 不要なデータを送信しないため、ネットワークの帯域幅を節約できます。
  • データ処理の効率化: 取得したデータが少ないため、アプリケーション側でのデータ処理が迅速になります。

例えば、以下のように必要な属性のみを指定することで、不要なデータを取得しないように設定できます。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent(); // フォームの初期化
        DirectorySearcher searcher = new DirectorySearcher();
        searcher.Filter = "(objectClass=user)"; // ユーザーオブジェクトをフィルタリング
        searcher.PropertiesToLoad.Add("cn"); // Common Nameを追加
        searcher.PropertiesToLoad.Add("mail"); // メールアドレスを追加
    }
}

検索結果の効率的な処理

検索結果を効率的に処理するためには、取得した属性を適切に扱うことが重要です。

以下のポイントに注意することで、検索結果の処理を最適化できます。

  • ループ処理の最適化: 検索結果をループ処理する際、必要な属性のみを取得し、無駄な処理を避けることが重要です。
  • データ構造の選択: 取得したデータを格納する際、適切なデータ構造を選ぶことで、アクセス速度を向上させることができます。

以下は、検索結果を効率的に処理する例です。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent(); // フォームの初期化
        DirectorySearcher searcher = new DirectorySearcher();
        searcher.Filter = "(objectClass=user)"; // ユーザーオブジェクトをフィルタリング
        searcher.PropertiesToLoad.Add("cn"); // Common Nameを追加
        searcher.PropertiesToLoad.Add("mail"); // メールアドレスを追加
        SearchResultCollection results = searcher.FindAll(); // 検索を実行
        List<string> userInfoList = new List<string>(); // ユーザー情報を格納するリスト
        foreach (SearchResult result in results)
        {
            string commonName = result.Properties["cn"][0].ToString(); // Common Nameを取得
            string email = result.Properties["mail"][0].ToString(); // メールアドレスを取得
            userInfoList.Add($"名前: {commonName}, メール: {email}"); // リストに追加
        }
        // 取得したユーザー情報を表示
        MessageBox.Show(string.Join("\n", userInfoList)); // 結果を表示
    }
}

このコードでは、検索結果をリストに格納し、最後にまとめて表示することで、効率的な処理を実現しています。

PropertiesToLoadを活用し、必要なデータのみを取得することで、全体的なパフォーマンスを向上させることができます。

応用例

フィルタリングと組み合わせた検索

PropertiesToLoadを使用する際に、フィルタリングを組み合わせることで、特定の条件に合致するデータを効率的に取得できます。

例えば、特定の部門に所属するユーザーを検索する場合、以下のようにフィルタを設定します。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent(); // フォームの初期化
        DirectorySearcher searcher = new DirectorySearcher();
        searcher.Filter = "(&(objectClass=user)(department=Sales))"; // Sales部門のユーザーをフィルタリング
        searcher.PropertiesToLoad.Add("cn"); // Common Nameを追加
        searcher.PropertiesToLoad.Add("mail"); // メールアドレスを追加
        SearchResultCollection results = searcher.FindAll(); // 検索を実行
        foreach (SearchResult result in results)
        {
            string commonName = result.Properties["cn"][0].ToString(); // Common Nameを取得
            string email = result.Properties["mail"][0].ToString(); // メールアドレスを取得
            MessageBox.Show($"ユーザー名: {commonName}\nメール: {email}"); // 結果を表示
        }
    }
}

このコードでは、department属性を使用して、Sales部門に所属するユーザーのみを取得しています。

フィルタリングを活用することで、必要なデータをより効率的に取得できます。

検索結果のキャッシュ

検索結果をキャッシュすることで、同じ検索を繰り返す際のパフォーマンスを向上させることができます。

キャッシュを使用することで、LDAPサーバーへのリクエストを減らし、応答時間を短縮できます。

以下は、検索結果をキャッシュする例です。

partial class MyForm : Form
{
    private List<string> cachedUserInfo; // キャッシュ用のリスト
    public MyForm()
    {
        InitializeComponent(); // フォームの初期化
        cachedUserInfo = new List<string>(); // キャッシュの初期化
    }
    private void LoadUserInfo()
    {
        if (cachedUserInfo.Count > 0) // キャッシュが存在する場合
        {
            MessageBox.Show(string.Join("\n", cachedUserInfo)); // キャッシュを表示
            return;
        }
        DirectorySearcher searcher = new DirectorySearcher();
        searcher.Filter = "(objectClass=user)"; // ユーザーオブジェクトをフィルタリング
        searcher.PropertiesToLoad.Add("cn"); // Common Nameを追加
        searcher.PropertiesToLoad.Add("mail"); // メールアドレスを追加
        SearchResultCollection results = searcher.FindAll(); // 検索を実行
        foreach (SearchResult result in results)
        {
            string commonName = result.Properties["cn"][0].ToString(); // Common Nameを取得
            string email = result.Properties["mail"][0].ToString(); // メールアドレスを取得
            cachedUserInfo.Add($"名前: {commonName}, メール: {email}"); // キャッシュに追加
        }
        MessageBox.Show(string.Join("\n", cachedUserInfo)); // 結果を表示
    }
}

このコードでは、最初に検索結果をキャッシュし、次回以降はキャッシュからデータを取得することで、パフォーマンスを向上させています。

大規模なディレクトリでの使用

大規模なディレクトリでPropertiesToLoadを使用する場合、効率的な検索とデータ取得が重要です。

特に、数万件以上のエントリがある場合、適切なフィルタリングと属性の指定が必要です。

以下は、大規模なディレクトリでの使用例です。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent(); // フォームの初期化
        DirectorySearcher searcher = new DirectorySearcher();
        searcher.Filter = "(objectClass=user)"; // ユーザーオブジェクトをフィルタリング
        searcher.PropertiesToLoad.Add("cn"); // Common Nameを追加
        searcher.PropertiesToLoad.Add("mail"); // メールアドレスを追加
        searcher.PageSize = 1000; // ページサイズを設定(1回の検索で取得するエントリ数)
        SearchResultCollection results = searcher.FindAll(); // 検索を実行
        foreach (SearchResult result in results)
        {
            string commonName = result.Properties["cn"][0].ToString(); // Common Nameを取得
            string email = result.Properties["mail"][0].ToString(); // メールアドレスを取得
            // 取得した情報を処理する(例: リストに追加、表示など)
        }
    }
}

このコードでは、PageSizeプロパティを設定することで、大規模なディレクトリからのデータ取得を効率化しています。

これにより、検索結果をページングし、メモリの使用量を抑えつつ、必要なデータを取得することができます。

大規模なデータセットを扱う際には、適切な設定が重要です。

よくある質問

PropertiesToLoadに指定できる属性はどこで確認できますか?

PropertiesToLoadに指定できる属性は、LDAPスキーマに基づいて定義されています。

これらの属性は、Active DirectoryやLDAPサーバーのドキュメントに記載されています。

具体的には、以下の方法で確認できます。

  • Active Directoryスキーマのドキュメント: Microsoftの公式ドキュメントやLDAPの仕様書を参照することで、利用可能な属性の一覧を確認できます。
  • LDAPブラウザツール: LDAPブラウザを使用して、サーバーに接続し、スキーマを直接確認することができます。

これにより、どの属性が利用可能かを視覚的に確認できます。

PropertiesToLoadを設定しないとどうなりますか?

PropertiesToLoadを設定しない場合、DirectorySearcherはデフォルトで多くの属性を取得しようとします。

これにより、以下のような影響があります。

  • パフォーマンスの低下: 不要な属性も取得されるため、検索処理が遅くなる可能性があります。
  • メモリ使用量の増加: 取得するデータが多くなるため、メモリの使用量が増加します。
  • ネットワーク負荷の増加: 不要なデータが送信されるため、ネットワークの帯域幅を無駄に消費します。

このため、必要な属性のみを指定することが推奨されます。

取得した属性が空の場合はどうすればいいですか?

取得した属性が空の場合、以下の手順で対処できます。

  1. 属性の存在を確認: まず、指定した属性がLDAPサーバーに存在するかを確認します。

属性名が正しいか、またはそのユーザーやオブジェクトにその属性が設定されているかを確認します。

  1. エラーハンドリング: 取得した属性が空である場合に備えて、エラーハンドリングを実装します。

例えば、属性が空の場合はデフォルト値を設定するか、エラーメッセージを表示することが考えられます。

  1. デバッグ: 取得したデータをデバッグし、どの段階で問題が発生しているかを特定します。

これにより、問題の原因を特定しやすくなります。

以下は、取得した属性が空の場合のエラーハンドリングの例です。

if (result.Properties["mail"].Count > 0) // メールアドレスが存在するか確認
{
    string email = result.Properties["mail"][0].ToString(); // メールアドレスを取得
}
else
{
    // メールアドレスが空の場合の処理
    MessageBox.Show("メールアドレスが設定されていません。"); // エラーメッセージを表示
}

このように、取得した属性が空の場合には、適切な対処を行うことが重要です。

まとめ

この記事では、C#のDirectorySearcherクラスにおけるPropertiesToLoadの使い方やその利点について詳しく解説しました。

特に、必要な属性のみを指定することで、検索のパフォーマンスを向上させる方法や、フィルタリングを活用した効率的なデータ取得の手法について触れました。

これを機に、実際のアプリケーション開発において、LDAP検索を最適化するための具体的な実践例を試してみてください。

当サイトはリンクフリーです。出典元を明記していただければ、ご自由に引用していただいて構いません。

関連カテゴリーから探す

  • URLをコピーしました!
目次から探す