ルックアップとリストのリレーションシップ

最終更新日: 2010年12月1日

適用対象: SharePoint Foundation 2010

この記事の内容
リストのリレーションシップとデータ整合性
リストのリレーションシップを作成する
複数列ルックアップを作成する
リストのリレーションシップを確認する
関連アイテムを確認する

Microsoft SharePoint Foundation では、ルックアップ フィールドは、他のリストから値を取得するように構成されたフィールドです。ルックアップ フィールドをリストに追加すると、そのリストとデータを提供するリスト間にリレーションシップが作成されます。

2 つのリストをどのように呼ぶかは、どの観点からリストを見るかによって決まります。ルックアップ フィールドの観点から見た場合、データを提供するリストはターゲット リスト、データの取得元フィールドはターゲット フィールドです。ターゲット リストの観点から見た場合、ルックアップ フィールドが含まれるリストは関連リスト、ルックアップ フィールド自体は関連フィールドです。

ヒントヒント

SPList クラスには、リストを参照するルックアップ フィールドを検出する際に使用できる GetRelatedFields メソッドが含まれます。

便宜上、また混乱を防ぐため、2 つのリストには親子のリレーションシップがあると言われることがあります。子リストにはルックアップ フィールドが含まれ、親リストには、ルックアップ フィールドのターゲットであるデータ ソースが含まれます。

リストのリレーションシップとデータ整合性

Microsoft SharePoint Foundation 2010 では、親リストのアイテムに対して削除の制約が適用されるように、子リストでルックアップ フィールドを構成できます。ユーザー インターフェイスを使用してルックアップ列を作成または編集する場合は、[リレーションシップの動作を実行する] のオプションを選択します。このオプションを選択すると、[削除制限] または [連鎖削除] のどちらかを選択できます。制限削除を選択した場合、親リストのアイテムが子リストの 1 つ以上の関連アイテムによって参照されていると、その親リストのアイテムは削除されません。連鎖削除を選択した場合、親リストからアイテムを削除すると、子リストにあるすべての関連アイテムが一緒に削除されます。

コードでこれと同じ動作を有効にするには、SPFieldLookup オブジェクトの RelationshipDeleteBehavior プロパティを、SPRelationshipDeleteBehavior 列挙の値である Restrict または Cascade のどちらかに設定します。

重要重要

SharePoint Foundation で制限削除または連鎖削除のどちらかを行うには、ルックアップ フィールドにインデックスが設定されている必要があります。インデックスを設定するには、フィールドの Indexed プロパティを true に設定します。

削除の制約の目的は参照整合性を適用することです。ルックアップ フィールドがターゲット リストに存在しないアイテムを参照していると、そのルックアップ フィールドに含まれるアイテムは孤立してしまいます。これを避けたいときに、制約を適用します。

たとえば、Customers と Addresses の 2 つのリストがあるとします。Customer ID という名前のルックアップ フィールドを Addresses リストに追加し、この 2 つのリストを関連付けることにしました。そのルックアップ フィールドは、Customers リストの ID フィールドを参照するように設定します。ルックアップを構成したら、Customers リストからの削除を Addresses リストに連鎖させることで、2 つのリスト間のリレーションシップに制約を適用します。連鎖削除を選択すると参照整合性が適用され、Addresses リストが孤立したアドレスを取得しないようになります。アイテムが Customers から削除されると必ず、Addresses の関連アイテムが自動的に削除されます。

また、Pending Orders リストもあり、このリストも Address リストのように、Customers リストの ID フィールドを参照するルックアップ フィールドによって Customers リストに関連付けられています。Pending Orders リストに保留中の注文がある場合、その注文の顧客のレコードが Customers リストから削除されないようにするには、親リスト Customers からの削除を制限するように、Pending Orders のルックアップ フィールドを構成します。これにより、参照整合性を適用することができます。

連鎖削除または制限削除を選択すると、ルックアップ フィールドの値が設定されるときに、副作用としてその値が検証されます。ユーザー インターフェイスを使って新しいアイテムを作成するとき、ターゲット リストのアイテムが 20 未満の場合は、ドロップダウン リストを備えたルックアップ列がフォーム上に表示されます。この場合、ユーザーが選択できるのは有効な値のみに限られます。ターゲットのアイテムが 20 を超える場合は、ユーザーは別のコントロールを使用して値を入力する必要があります。この場合、無効な値を入力すると、その値は赤の評価テキストで表示されます。オブジェクト モデルを使用してルックアップ フィールドの値を設定するときも、同様の検証が行われます。この場合、指定された値が、ターゲット リストにある既存のアイテムを参照していないと、SharePoint Foundation によって例外がスローされます。

削除の制約をルックアップ リストに適用しないというオプションもあります。たとえば、Addresses および Pending Orders のほかに、Complete Orders リストがあるとします。このリストも、他の関連リストと同様に、Customers リストの ID フィールドを参照します。注文した顧客の記録を保存する必要がなくなっても、完了した注文の記録を残しておく場合、参照整合性は問題にならないので、ルックアップ リストからの削除には制約を適用しません。この場合、Customers リストからアイテムを削除しても、Complete Orders リストには何の影響もありません。

リストのリレーションシップを作成する

ルックアップ フィールドは、SPFieldLookup クラスのインスタンスによって表されます。クラスにはコンストラクターが含まれますが、ルックアップ フィールドを最も簡単に作成するには、SPFieldCollection クラスの AddLookup メソッドを呼び出します。AddLookup メソッドに含まれるオーバーロードを使用すると、ルックアップを作成しているサイトとは異なる Web サイトにあるリストへのルックアップを作成できます。

注意

異なる Web サイトのリスト間にリレーションシップを作成できますが、そのリレーションシップに対して制限を設定することはできません。SharePoint Foundation では、Web 間のルックアップには参照整合性が適用されません。

ルックアップ列をリストに追加するには

  1. Fields プロパティにアクセスし、リストのフィールド コレクションへの参照を取得します。

  2. SPFieldCollection オブジェクトの AddLookup メソッドを呼び出して、2 番目のパラメーターでルックアップ リスト (データ ソース) の ID を渡します。

    AddLookup メソッドは、新しいフィールドの内部列を示す文字列を返します。

  3. GetFieldByInternalName メソッドを呼び出して、新しいフィールドを表す SPFieldLookup オブジェクトへの参照を取得し、AddLookup メソッドによって返された文字列を引数として渡します。

    GetFieldByInternalName メソッドは SPField オブジェクトを返します。これを、SPFieldLookup 型にキャストする必要があります。

  4. LookupField プロパティを、ルックアップ リストのフィールドの内部名に設定します。SPFieldLookup オブジェクトは、これをデータ ソースとして使用します。

    LookupField プロパティのターゲットは、次のフィールド型のいずれかにする必要があります。

    さらに、出力がテキストの場合は、SPFieldCalculated 型をターゲットにできます。詳細については、OutputType プロパティを参照してください。ルックアップがフィールドに対して有効になっている場合は、SPFieldComputed 型をターゲットにできます。詳細については、EnableLookup プロパティを参照してください。

  5. (オプション) None (既定) 以外の削除動作を指定する場合は、Indexed プロパティを true に設定します。

  6. (オプション) SPRelationshipDeleteBehavior 列挙値で RelationshipDeleteBehavior プロパティを設定します。

    重要重要

    Cascade または Restrict を指定するには、ルックアップ リストでの ManageLists 権限がユーザーに必要です。詳細については、SPBasePermissions 列挙を参照してください。

    さらに、次の場合は、リレーションシップの動作の設定が失敗します。

    • ルックアップ フィールドで複数の値が許可されている。

      RelationshipDeleteBehavior プロパティを設定する前に、AllowMultipleValues プロパティが false を返すことを確認します。

    • ルックアップ フィールドに対して既存のリスト アイテムの値が無効である。

      この状態は、ルックアップ フィールドの RelationshipDeleteBehavior プロパティが None に設定され、誰かがそのルックアップ フィールドの参照先であるターゲット リストのアイテムを削除したときに発生します。これにより、ルックアップ フィールドは孤立し、フィールドの値は無効になります。孤立したルックアップ フィールドがリストに含まれる場合、リレーションシップの動作を適用することはできません。

    • ルックアップ フィールドが他の Web サイトのリストを参照している。

      ルックアップ フィールドの LookupWebId プロパティの値を確認します。

    • リストのアイテム数が大きなリストの最大セットを超えている。

      リストの ItemCount プロパティによって返された値と、Web アプリケーションの MaxItemsPerThrottledOperation プロパティによって返された値を比較します。

  7. Update メソッドを呼び出して、オブジェクトに対する変更をコミットします。

次の例は、Customers リストと Pending Orders リスト間のリレーションシップを作成するコンソール アプリケーションです。このアプリケーションでは、AddLookup メソッドを呼び出して Customer ID というルックアップ フィールドを Pending Orders リストに追加し、Customer リストの ID フィールドのフィールドを参照するように設定します。新しい Customer ID フィールドはインデックスが付けられ、ルックアップ リストからの削除を制限するように設定されます。

using System;
using Microsoft.SharePoint;

namespace RelatedLists
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SPSite siteCollection = new SPSite("http://localhost"))
            {
                using (SPwebsite = siteCollection.OpenWeb())
                {
                    SPList lookupList = site.Lists.TryGetList("Customers");
                    SPList relatedList = site.Lists.TryGetList("Pending Orders");

                    if (lookupList != null && relatedList != null)
                    {
                        string strPrimaryCol = relatedList.Fields.AddLookup("Customer ID", lookupList.ID, true);
                        SPFieldLookup primaryCol = (SPFieldLookup)relatedList.Fields.GetFieldByInternalName(strPrimaryCol);

                        primaryCol.LookupField = lookupList.Fields["ID"].InternalName;
                        primaryCol.Indexed = true;
                        primaryCol.RelationshipDeleteBehavior = SPRelationshipDeleteBehavior.Restrict;
                        primaryCol.Update();
                    }
                }
            }
            Console.Write("\nPress ENTER to continue...");
            Console.ReadLine();
        }
    }
}
Imports System
Imports Microsoft.SharePoint

Module ConsoleApp

    Sub Main()
        Using siteCollection As New SPSite("http://localhost")
            Using site As SPWeb = siteCollection.OpenWeb()
                Dim lookupList As SPList = site.Lists.TryGetList("Customers")
                Dim relatedList As SPList = site.Lists.TryGetList("Pending Orders")

                If lookupList IsNot Nothing AndAlso relatedList IsNot Nothing Then
                    Dim strPrimaryCol As String = relatedList.Fields.AddLookup("Customer ID", lookupList.ID, True)
                    Dim primaryCol As SPFieldLookup = _
                        DirectCast(relatedList.Fields.GetFieldByInternalName(strPrimaryCol), SPFieldLookup)

                    primaryCol.LookupField = lookupList.Fields("ID").InternalName
                    primaryCol.Indexed = True
                    primaryCol.RelationshipDeleteBehavior = SPRelationshipDeleteBehavior.Restrict
                    primaryCol.Update()
                End If
            End Using
        End Using
        Console.Write(vbLf & "Press ENTER to continue...")
        Console.ReadLine()
    End Sub
End Module

複数列ルックアップを作成する

SharePoint Foundation 2010 では、同じルックアップ リストに対して複数列ルックアップを作成できます。たとえば、Customers と Pending Orders の 2 つのリストがあるとします。この 2 つのリスト間のリレーションシップは、Customer ID 列を Pending Orders リストに追加し、Customers リストの ID フィールドの列を参照させることで作成しました。さらに、Pending Orders リストのアイテムを確認するときに、注文自体に関する情報と一緒に、注文した顧客の情報が表示されるようにしたいと考えています。そこで、プライマリ ルックアップ列である Customer ID のほかに、3 つのセカンダリ ルックアップ列を追加して、顧客の姓、名、および電話番号を表示します。

複数列ルックアップのセカンダリ列は、ルックアップ リストに対するリレーションシップのプライマリ列によって決まります。セカンダリ ルックアップ列に対して削除の制約を作成することはできません。プライマリ列に対して設定された制約のみが、ルックアップ リストに適用される制約になります。

セカンダリ ルックアップ列を作成する手順は、プライマリ ルックアップ列を作成する手順とほぼ同じです。重要な違いは、AddLookup メソッドではなく、SPFieldCollection クラスの AddDependentLookup メソッドを呼び出してフィールドを作成するという点です。AddDependentLookup メソッドには 2 つのパラメーターがあります。1 つはセカンダリ フィールドに使用する表示名、もう 1 つはプライマリ フィールドの ID です。

次の例は、Customers リストと Pending Orders リスト間のリレーションシップを作成するコンソール アプリケーションです。このアプリケーションでは、AddLookup メソッドを呼び出して Customer ID というプライマリ ルックアップ フィールドを Pending Orders リストに追加し、Customer リストの ID フィールドでフィールドを参照するように設定します。新しい Customer ID フィールドはインデックスが付けられ、ルックアップ リストからの削除を制限するように設定されます。

このアプリケーションでは、プライマリ ルックアップ フィールドの作成後に、First Name、Last Name、および Phone とうい名前の 3 つのセカンダリ フィールドが作成されます。ここでは、これらのフィールドを作成するために、Pending Order リストのフィールド コレクションを表すオブジェクトの AddDependentLookup メソッドが呼び出されています。

using System;
using Microsoft.SharePoint;

namespace RelatedLists
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SPSite siteCollection = new SPSite("http://localhost"))
            {
                using (SPwebsite = siteCollection.OpenWeb())
                {
                    SPList lookupList = site.Lists.TryGetList("Customers");
                    SPList relatedList = site.Lists.TryGetList("Pending Orders");

                    if (lookupList != null && relatedList != null)
                    {

                        // Create the primary column.
                        string strPrimaryCol = relatedList.Fields.AddLookup("Customer ID", lookupList.ID, true);
                        SPFieldLookup primaryCol = (SPFieldLookup)relatedList.Fields.GetFieldByInternalName(strPrimaryCol);

                        primaryCol.LookupField = lookupList.Fields["ID"].InternalName;
                        primaryCol.Indexed = true;
                        primaryCol.RelationshipDeleteBehavior = SPRelationshipDeleteBehavior.Restrict;
                        primaryCol.Update();


                        // Create the secondary columns.

                        string strFirstNameCol = relatedList.Fields.AddDependentLookup("First Name", primaryCol.Id);
                        SPFieldLookup firstNameCol = (SPFieldLookup)relatedList.Fields.GetFieldByInternalName(strFirstNameCol);
                        firstNameCol.LookupField = lookupList.Fields["First Name"].InternalName;
                        firstNameCol.Update();

                        string strLastNameCol = relatedList.Fields.AddDependentLookup("Last Name", primaryCol.Id);
                        SPFieldLookup lastNameCol = (SPFieldLookup)relatedList.Fields.GetFieldByInternalName(strLastNameCol);
                        lastNameCol.LookupField = lookupList.Fields["Last Name"].InternalName;
                        lastNameCol.Update();

                        string strPhoneCol = relatedList.Fields.AddDependentLookup("Phone", primaryCol.Id);
                        SPFieldLookup phoneCol = (SPFieldLookup)relatedList.Fields.GetFieldByInternalName(strPhoneCol);
                        phoneCol.LookupField = lookupList.Fields["Phone"].InternalName;
                        phoneCol.Update();
                    }
                }
            }
            Console.Write("\nPress ENTER to continue...");
            Console.ReadLine();
        }
    }
}
Imports System
Imports Microsoft.SharePoint

Module ConsoleApp

    Sub Main()
        Using siteCollection As New SPSite("http://localhost")
            Using site As SPWeb = siteCollection.OpenWeb()
                Dim lookupList As SPList = site.Lists.TryGetList("Customers")
                Dim relatedList As SPList = site.Lists.TryGetList("Pending Orders")

                If lookupList IsNot Nothing AndAlso relatedList IsNot Nothing Then

                    ' Create the primary column.
                    Dim strPrimaryCol As String = relatedList.Fields.AddLookup("Customer ID", lookupList.ID, True)
                    Dim primaryCol As SPFieldLookup = _
                        DirectCast(relatedList.Fields.GetFieldByInternalName(strPrimaryCol), SPFieldLookup)

                    primaryCol.LookupField = lookupList.Fields("ID").InternalName
                    primaryCol.Indexed = True
                    primaryCol.RelationshipDeleteBehavior = SPRelationshipDeleteBehavior.Restrict
                    primaryCol.Update()


                    ' Create the secondary columns.

                    Dim strFirstNameCol As String = relatedList.Fields.AddDependentLookup("First Name", primaryCol.Id)
                    Dim firstNameCol As SPFieldLookup = _
                        DirectCast(relatedList.Fields.GetFieldByInternalName(strFirstNameCol), SPFieldLookup)
                    firstNameCol.LookupField = lookupList.Fields("First Name").InternalName
                    firstNameCol.Update()

                    Dim strLastNameCol As String = relatedList.Fields.AddDependentLookup("Last Name", primaryCol.Id)
                    Dim lastNameCol As SPFieldLookup = _
                        DirectCast(relatedList.Fields.GetFieldByInternalName(strLastNameCol), SPFieldLookup)
                    lastNameCol.LookupField = lookupList.Fields("Last Name").InternalName
                    lastNameCol.Update()

                    Dim strPhoneCol As String = relatedList.Fields.AddDependentLookup("Phone", primaryCol.Id)
                    Dim phoneCol As SPFieldLookup = _
                        DirectCast(relatedList.Fields.GetFieldByInternalName(strPhoneCol), SPFieldLookup)
                    phoneCol.LookupField = lookupList.Fields("Phone").InternalName
                    phoneCol.Update()
                End If
            End Using
        End Using
        Console.Write(vbLf & "Press ENTER to continue...")
        Console.ReadLine()
    End Sub
End Module

リストのリレーションシップを確認する

関連リストのどのフィールドがルックアップ リストの情報によって決まるかを確認するには、ルックアップ リストを表す SPList オブジェクトで GetRelatedFields メソッドを呼び出します。このメソッドは、次のプロパティを持つ SPRelatedField オブジェクトのコレクションを返します。

  • FieldId。関連リストのルックアップ フィールドの Id を取得します。

  • ListId。関連リストの ID を取得します。

  • WebId。関連リストが配置されている Web サイトの ID を取得します。

  • RelationshipDeleteBehavior。リレーションシップに定義された削除の制約を取得します。

GetRelatedFields メソッドには、特定の削除の制約を指定するこれらのフィールドに関する情報のみを取得できるオーバーロードが含まれます。

複数列ルックアップのプライマリ列を表す関連フィールドに対してのみ情報が返されます。セカンダリ列の情報を取得するには、プライマリ列を表す SPFieldLookup オブジェクトの GetDependentLookupInternalNames メソッドを呼び出します。

次の例は、他のリストのルックアップ フィールドにデータを提供する Customers リストのフィールドに関する情報をレポートするコンソール アプリケーションです。このアプリケーションでは、プライマリ列を表す関連フィールドごとに GetDependentLookupInternalNames メソッドを呼び出して、セカンダリ列を表すフィールドのリストを取得します。

using System;
using System.Collections.Generic;
using Microsoft.SharePoint;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SPSite siteCollection = new SPSite("http://localhost"))
            {
                using (SPwebsite = siteCollection.OpenWeb())
                {
                    SPList targetList = site.Lists.TryGetList("Customers");
                    SPRelatedFieldCollection relatedFields = targetList.GetRelatedFields();

                    string strSeparator = new String('=', 70);
                    string strUnderline = new String('-', 20);
                    string strFormat = "Target Field: {0} | Related Field: {1}";

                    Console.WriteLine(strSeparator);
                    foreach (SPRelatedField fieldInfo in relatedFields)
                    {
                        using (SPWeb relatedSite = siteCollection.AllWebs[fieldInfo.WebId])
                        {
                            SPList relatedList = relatedSite.Lists.GetList(fieldInfo.ListId, false);
                            SPFieldLookup relatedField = relatedList.Fields[fieldInfo.FieldId] as SPFieldLookup;
                            SPField targetField = targetList.Fields.GetFieldByInternalName(relatedField.LookupField);

                            Console.WriteLine("\nTarget List: {0} ({1}) | Related List: {2} ({3})", targetList.Title, site.Title, relatedList.Title, relatedSite.Title);

                            Console.WriteLine("\nPrimary Column");
                            Console.WriteLine(strUnderline);
                            Console.WriteLine(strFormat, targetField.Title, relatedField.Title);
                            Console.WriteLine("Deletion behavior: {0}", relatedField.RelationshipDeleteBehavior);

                            Console.WriteLine("\nSecondary Columns");
                            Console.WriteLine(strUnderline);

                            List<string> dependents = relatedField.GetDependentLookupInternalNames();
                            for (int i = 0; i < dependents.Count; i++)
                            {
                                SPFieldLookup lookup = relatedList.Fields.GetFieldByInternalName(dependents[i]) as SPFieldLookup;
                                SPField field = targetList.Fields.GetFieldByInternalName(lookup.LookupField);

                                Console.WriteLine(strFormat, field.Title, lookup.Title);
                            }
                            Console.WriteLine();
                            Console.WriteLine(strSeparator);
                        }
                    }
                }
            }
            Console.Write("\nPress ENTER to continue...");
            Console.ReadLine();
        }
    }
}
Imports System
Imports System.Collections.Generic
Imports Microsoft.SharePoint

Module ConsoleApp

    Sub Main()
        Using siteCollection As New SPSite("http://localhost")
            Using site As SPWeb = siteCollection.OpenWeb()
                Dim targetList As SPList = site.Lists.TryGetList("Customers")
                Dim relatedFields As SPRelatedFieldCollection = targetList.GetRelatedFields()

                Dim strSeparator As String = New [String]("="c, 70)
                Dim strUnderline As String = New [String]("-"c, 20)
                Dim strFormat As String = "Target Field: {0} | Related Field: {1}"

                Console.WriteLine(strSeparator)
                For Each fieldInfo As SPRelatedField In relatedFields
                    Using relatedSite As SPWeb = siteCollection.AllWebs(fieldInfo.WebId)
                        Dim relatedList As SPList = relatedSite.Lists.GetList(fieldInfo.ListId, False)
                        Dim relatedField As SPFieldLookup = TryCast(relatedList.Fields(fieldInfo.FieldId), SPFieldLookup)
                        Dim targetField As SPField = targetList.Fields.GetFieldByInternalName(relatedField.LookupField)

                        Console.WriteLine(vbLf & "Target List: {0} ({1}) | Related List: {2} ({3})", _
                                          targetList.Title, site.Title, relatedList.Title, relatedSite.Title)

                        Console.WriteLine(vbLf & "Primary Column")
                        Console.WriteLine(strUnderline)
                        Console.WriteLine(strFormat, targetField.Title, relatedField.Title)
                        Console.WriteLine("Deletion behavior: {0}", relatedField.RelationshipDeleteBehavior)

                        Console.WriteLine(vbLf & "Secondary Columns")
                        Console.WriteLine(strUnderline)

                        Dim dependents As List(Of String) = relatedField.GetDependentLookupInternalNames()
                        Dim i As Integer = 0
                        While i < dependents.Count
                            Dim lookup As SPFieldLookup = _
                                TryCast(relatedList.Fields.GetFieldByInternalName(dependents(i)), SPFieldLookup)
                            Dim field As SPField = targetList.Fields.GetFieldByInternalName(lookup.LookupField)

                            Console.WriteLine(strFormat, field.Title, lookup.Title)
                            i = i + 1
                        End While
                        Console.WriteLine()
                        Console.WriteLine(strSeparator)
                    End Using
                Next
            End Using
        End Using
        Console.Write(vbLf & "Press ENTER to continue...")
        Console.ReadLine()
    End Sub
End Module

コンソール アプリケーションは以下のような出力を表示します。

======================================================================

Target List: Customers (Team Site) | Related List: Complete Orders (Team Site)

Primary Column
--------------------
Target Field: ID | Related Field: Customer ID
Deletion behavior: None

Secondary Columns
--------------------
Target Field: Last Name | Related Field: Customer

======================================================================

Target List: Customers (Team Site) | Related List: Addresses (Team Site)

Primary Column
--------------------
Target Field: ID | Related Field: Customer ID
Deletion behavior: Cascade

Secondary Columns
--------------------
Target Field: Last Name | Related Field: Last Name
Target Field: First Name | Related Field: First Name

======================================================================

Target List: Customers (Team Site) | Related List: Pending Orders (Team Site)

Primary Column
--------------------
Target Field: ID | Related Field: Customer ID
Deletion behavior: Restrict

Secondary Columns
--------------------
Target Field: First Name | Related Field: First Name
Target Field: Last Name | Related Field: Last Name
Target Field: Phone | Related Field: Phone

======================================================================

Press ENTER to continue...

関連アイテムを確認する

SharePoint Foundation 2010 のユーザー インターフェイスのリボンには [関連リストの挿入] ボタンが表示されています。ユーザーはこのボタンを使用して関連リスト Web パーツを追加し、リストが表示されるページを編集できます。関連リスト Web パーツには、現在のリストで選択されているアイテムに関連する、他のリストのアイテムが表示されます。たとえば、関連リスト Web パーツを Customer リストに追加して、ユーザーが顧客レコードを選択し、選択した顧客に関連する Pending Orders リストでアイテムを確認できるようにします。

関連アイテムに関する同じ情報をオブジェクト モデルで取得するには、ルックアップ リストを表す SPList オブジェクトの GetRelatedFields への呼び出しによって返された SPRelatedField オブジェクトのプロパティを使用します。

次の例は、Customers リストからアイテムを取得し、サイト コレクションの他のリストの関連アイテムを検索するコンソール アプリケーションです。アプリケーションの PrintRelatedItems メソッドによって力作業が行われ、ルックアップ リストのアイテムと SPRelatedField オブジェクトの情報を使用し、関連するリストに対するクエリを作成します。

using System;
using Microsoft.SharePoint;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SPSite siteCollection = new SPSite("http://localhost"))
            {
                using (SPwebsite = siteCollection.OpenWeb())
                {
                    int customerID = 1;

                    SPList list = site.Lists.TryGetList("Customers");
                    if (list != null)
                    {

                        // Get a customer record.
                        SPListItem customerRecord = null;
                        try
                        {
                            customerRecord = list.GetItemById(customerID);
                        }
                        catch (ArgumentException ex)
                        {
                            Console.WriteLine(ex.Message);
                        }

                        // Print related items.
                        if (customerRecord != null)
                        {
                            Console.WriteLine("Customer: {0} {1}", 
                            customerRecord[SPBuiltInFieldId.FirstName], customerRecord[SPBuiltInFieldId.Title]);

                            // Get related list items.
                            SPRelatedFieldCollection relatedFields = list.GetRelatedFields();
                            foreach (SPRelatedField fieldInfo in relatedFields)
                            {
                                using (SPWeb relatedSite = siteCollection.AllWebs[fieldInfo.WebId])
                                {
                                    PrintRelatedItems(customerRecord, relatedSite, fieldInfo);
                                }
                            }
                        }
                    }
                }
            }
            Console.Write("\nPress ENTER to continue...");
            Console.ReadLine();
        }

        static void PrintRelatedItems(SPListItem match, SPwebsite, SPRelatedField fieldInfo)
        {
            SPList targetList = fieldInfo.LookupList;
            SPList relatedList = site.Lists[fieldInfo.ListId];

            SPFieldLookup relatedField = relatedList.Fields[fieldInfo.FieldId] as SPFieldLookup;
            SPField targetField = targetList.Fields.GetFieldByInternalName(relatedField.LookupField);

            object value = match[targetField.Id];

            SPQuery q = new SPQuery();
            q.Query = string.Format(@"<Where>
                                            <Eq>
                                                <FieldRef Name=""{0}""/>
                                                <Value Type=""{1}"">{2}</Value>
                                            </Eq>
                                        </Where>", relatedField.InternalName, value.GetType(), value);

            SPListItemCollection items = relatedList.GetItems(q);

            if (items.Count > 0)
            {
                Console.WriteLine("\n{0} has {1} related items:", relatedList.Title, items.Count);
                foreach (SPListItem item in items)
                    Console.WriteLine(item.DisplayName);
            }
        }
    }
}
Imports System
Imports Microsoft.SharePoint

Module ConsoleApp

    Sub Main()
        Using siteCollection As New SPSite("http://localhost")
            Using site As SPWeb = siteCollection.OpenWeb()
                Dim customerID As Integer = 1

                Dim list As SPList = site.Lists.TryGetList("Customers")
                If list IsNot Nothing Then

                    ' Get a customer record.
                    Dim customerRecord As SPListItem = Nothing
                    Try
                        customerRecord = list.GetItemById(customerID)
                    Catch ex As ArgumentException
                        Console.WriteLine(ex.Message)
                    End Try

                    ' Print related items.
                    If customerRecord IsNot Nothing Then
                        Console.WriteLine("Customer: {0} {1}", _
                        customerRecord(SPBuiltInFieldId.FirstName), customerRecord(SPBuiltInFieldId.Title))

                        ' Get related list items.
                        Dim relatedFields As SPRelatedFieldCollection = list.GetRelatedFields()
                        For Each fieldInfo As SPRelatedField In relatedFields
                            Using relatedSite As SPWeb = siteCollection.AllWebs(fieldInfo.WebId)
                                PrintRelatedItems(customerRecord, relatedSite, fieldInfo)
                            End Using
                        Next
                    End If
                End If
            End Using
        End Using
        Console.Write(vbLf & "Press ENTER to continue...")
        Console.ReadLine()
    End Sub

    Sub PrintRelatedItems(ByVal match As SPListItem, ByVal site As SPWeb, ByVal fieldInfo As SPRelatedField)
        Dim targetList As SPList = fieldInfo.LookupList
        Dim relatedList As SPList = site.Lists(fieldInfo.ListId)

        Dim relatedField As SPFieldLookup = TryCast(relatedList.Fields(fieldInfo.FieldId), SPFieldLookup)
        Dim targetField As SPField = targetList.Fields.GetFieldByInternalName(relatedField.LookupField)

        Dim value As Object = match(targetField.Id)

        Dim q As New SPQuery()
        q.Query = String.Format( _
        "<Where><Eq><FieldRef Name=""{0}""/><Value Type=""{1}"">{2}</Value></Eq></Where>", _
        relatedField.InternalName, value.GetType(), value)

        Dim items As SPListItemCollection = relatedList.GetItems(q)

        If items.Count > 0 Then
            Console.WriteLine(vbLf & "{0} has {1} related items:", relatedList.Title, items.Count)
            For Each item As SPListItem In items
                Console.WriteLine(item.DisplayName)
            Next
        End If
    End Sub

End Module

関連項目

タスク

[方法] 複数列ルックアップを作成する

参照

SPFieldLookup

SPRelatedField

その他の技術情報

How to: Programmatically Set the Delete Behavior on a Lookup Field (英語)