多対多のリレーションシップの使用
多対多のリレーションシップでは、複数の行に同じデータが関連付けられている場合に柔軟に追跡することができます。 一対多のリレーションシップとは異なり、多対多のリレーションシップには主テーブルの概念がありません。 多対多のリレーションシップは完全に対称であり、リレーションシップのどちらからでも関連付けられている行のセットにアクセスできます。 以下のセクションでは、引き続き Contoso 社の共有ワークスペース データ モデルのデスクとデスクの機能の項目を使用して、キャンバス アプリで多対多のリレーションシップを使用する方法について説明します。 次の図は、リレーションシップとそれに対応するデータを示しています。
それぞれのデスクには複数のデスクの機能の行を関連付けることができ、それぞれのデスクの機能には複数のデスクを関連付けることができます。 デスクの行からは、ThisItem.'Desk Features' 式を使用して、デスクの機能のセットにアクセスできます。 デスクの機能の行からは、ThisItem.Desks 式を使用して、その特定のデスクの機能に関連付けられているすべてのデスクにアクセスできます。
この式を使用して、次の例に示すように各デスクの値のコンマ区切りリストをギャラリーに表示することができます。
ラベルのテキストを入力するタスクを実行するには、ラベルの Text プロパティに次の式を設定します。
Concat(ThisItem.'Desk Features', Name, ",")
この式を使用する場合、特に多くのレコードがあるときは、Dataverse がデータにアクセスする方法によってパフォーマンスに影響があることに注意してください。 次のモニターの図は、デスクの一覧を取得するために getRows の呼び出しが 1 回行われていることを示しています。 それぞれのデスクに対して、そのデスクの機能を取得するために getNavigatedRowInTableRow の呼び出しが 1 回行われています。
その代わりに、ユーザーがギャラリーでデスクの行を 1 つ選択した後や、デスクの行の詳細にドリルダウンした後にのみデスクの機能を表示するほうがよい場合もあります。
このリレーションシップを使用するもう 1 つの方法は、ユーザーがデスクの機能を選択して、controlName.Selected.Desks プロパティを使用してギャラリーに項目を生成できるようにすることです。
この方法は、ボックスで選択を 1 つだけ許可する場合に役立ちます。 複数の選択を有効にする場合は、ロジックはより複雑になります。 現時点では、Power Fx には、このシナリオを実現するために必要な 2 つのコレクションの積集合を表す簡単な方法はありません。 次善策としては、 選択したすべての機能を反復処理して関連付けられているデスクを 1 つのコレクションにまとめ、重複を削除して、そのコレクションを項目のソースとして使用することなどができます。 ただし、この方法では Dataverse の複数の要求 (選択した機能ごとに 1 つ) により、テーブルの増大に伴ってパフォーマンスがすぐに低下します。
リレーションシップの定義
多対多のリレーションシップを定義する主な方法は、一対多のリレーションシップの場合と同様に Relate() 関数を使用することです。 主な違いは、このリレーションシップには主テーブルがないため、Relate() ではどちらのパラメーターを 1 つ目か 2 つ目にするかは関係ない点です。
フォームでの多対多のリレーションシップの管理は、多対一の検索列よりも複雑です。 多対多のリレーションシップは、フィールドの一覧で使用することができます。ただし、フォームにフィールドを追加しても、そのコントロールが機能する式が生成されず、次のようなエラーが表示されます。
この問題を解決するには、多対多のリレーションシップの反対側のテーブルの Items プロパティの Choices() 関数を更新します。 これを行うには、詳細タブでカードのロックを解除します。
この Contoso 社の例では、デスクの機能を使用します。 コントロールのロックを解除したら、Items プロパティにデータ ソースとして 'Desk Features' が表示されていることを確認します。
注
上記のシナリオでは、行を追加するためにフォームを使用しています。 編集機能をサポートするには、カードの DisplayMode プロパティを既定の設定の表示から編集に変更してください。
プロパティを調整すると、フォームのユーザー インターフェイスが機能し、ボックスで項目を選択できるようになります。 ただし、フォームを送信しようとすると、次のようなエラーが表示されます。
この問題を回避するには、Update プロパティをクリアし、フォームを送信してから多対多の関連付けを手動で処理します。
Update プロパティをクリアすると、フォームの送信が機能するようになります。 ただし、デスク テーブルとデスクの機能テーブルの行の間のリレーションシップは作成されません。 リレーションシップを定義するには、フォームを送信するために既定で使用されるチェック アイコンの OnSelect プロパティに以下のロジックを追加します。
ボックスで選択するデスクの機能をコレクションとして保存します。 この手順は、フォームを送信するとフィールドがリセットされて値が失われるため、必要です。
フォームを送信します。
保存したデスクの機能のコレクションを使用して、リレーションシップを定義します。
その他の設計のオプション
多対多のリレーションシップのユーザー エクスペリエンスは、複数選択列を使用する場合のエクスペリエンスと似ています。 複数選択の値は作成者によってあらかじめ決められており、無効にしたり保護したりすることはできません。 そのため、複数選択フィールドは、データがあまり変更されない場合に適しています (国/地域の一覧など)。 また、関連付けられているテーブルの行は、実行時に非アクティブ化、保護、追加することができます。 この機能により、多対多のリレーションシップは、実行時に柔軟性が必要な場合に適しています (取引先担当者がタグで多対多のリレーションシップを持ち、タグをユーザーが追加する必要がある場合のソリューションへのタグ付けなど)。
多対多のリレーションシップは、2 つのテーブルの行の間の関連付けを取得する場合に役立ちます。 行の間のリレーションシップには、他のデータを保存できません。 たとえば、取引先担当者テーブルと言語テーブルの間にリレーションシップがある場合、2 つの言語を話す人を追跡できます。
ただし、その人がそれぞれの言語をどのくらいの期間話しているのかや、どの程度話せるのかはわかりません。
その代わりによく使用される設計パターンは、独自の積集合テーブルを作成することです。 次の使用言語テーブルは、Dataverse の別のカスタム テーブルです。 このテーブルには、特定のリレーションシップを示すその他のプロパティの列を追加できます。 そのうえで、この新しいテーブルは取引先担当者や言語と N:1 のリレーションシップを持ちます。
アプリケーションからこれらのテーブルを使用するのは、一対多または多対一のリレーションシップを持つ他のテーブルを使用する場合と似ています。 追加のテーブルが含まれるため、ユーザー エクスペリエンスをスムーズにするために何らかの追加のロジックが必要な場合があります。 アプリケーションの要件を理解するとともに、多対多のリレーションシップで他のデータを追跡する必要があるかどうかを把握することが重要です。これは特に、テーブルを関連付けるときに判断する必要があります。