Lookup(関連レコードへの参照)を埋めるとき、内部 GUID を自前で取りに行くか、業務コードのままサーバーに委ねるかは、設計の細部に見えて環境移行の成否を決める。
結論を先に述べると、委譲が既定・自前は例外だ。
内部 GUID は dev/test/prod で別値になる環境ローカルな値であり、移送側が抱え込んだ瞬間に「build once, deploy many」の可搬性は失われる。
開発では動いたのに、本番で関係が空になった
Dataverse への取込定義を開発環境で完成させ、テストに展開した途端に Lookup フィールドが空になる。原因の多くは、開発環境で取得した内部 GUID をそのまま成果物に焼き込んでいることだ。
Dataverse の内部 GUID(レコードの主キー)は、レコードが作成された環境内で自動発番される。dev で a1b2c3... だったものが、test の同じ取引先レコードでは d4e5f6... になる。環境をまたぐたびに別の値になるため、GUID を直接参照した取込定義は他の環境で動かない。
Microsoft Learn の OData dataflow 移行ガイド(Migrate Data Between Dataverse Environments Using the OData Connector)は次のように明言している。
代替キーが必須。親テーブルの代替キーがないと子テーブルの Lookup カラムを設定できない。
業務コードは環境が変わっても同じ値を持つ。社内の取引先コード・品番・従業員番号——これらは dev でも prod でも変わらない。環境ローカルな GUID ではなく、環境不変の業務コードで Lookup を張るのが自然な理由はここにある。
責任分界:サーバーが ID を解決するのが自然
「業務コード → 内部 GUID」の変換をどちらが担うか。移送側がこれを担うとは、自分が所有していない ID を引きに行って管理下に置くことを意味する。これは**漏れた抽象(leaky abstraction)**と呼ばれる設計上の問題だ——本来サーバーが担うべき責任を移送側に漏らしている状態を指す。
内部 GUID を所有しているのは Dataverse のサーバー側だ。業務コードを受け取り、該当レコードの GUID を探して Lookup を解決する作業は、そのまま「ID の所有者」であるサーバーが担うのが責任分界として自然になる。
Dataverse の代替キー(Alternate Key)機能は、この委譲を実現する仕組みだ。あらかじめ業務コード列を代替キーとして登録しておけば、移送側は GUID を知ることなく Lookup を張れる。
委譲の実装:代替キーで Lookup を 1 コールで解決する
代替キーを使った Web API 呼び出しは次の形になる(Use an alternate key to reference a record、Microsoft Learn 2025)。
POST /api/data/v9.2/contacts
{
"firstname": "Jane",
"lastname": "Doe",
"[email protected]": "/accounts(accountnumber='ABC123')"
}
accountnumber='ABC123' は業務コードだ。GUID を事前に取得する必要はなく、単一 API コールでレコード作成と Lookup 解決が完了する。SDK(.NET)なら EntityReference(logicalName, keyName, keyValue) で同じ動作を得られる。事前 Retrieve は不要。
代替キーはインデックス管理されており、Microsoft Learn(Work with alternate keys)は Lookup 操作の性能向上を公式に明記している。
代替キーを定義する際には以下の制約を把握しておく。
| 制約項目 | 内容 |
|---|---|
| 使用禁止文字 | / < > * % & : \ ? + を含む値は GET/PATCH/DELETE が機能しない |
| 列セキュリティ | フィールドセキュリティ設定列は代替キーに使用不可 |
| 仮想テーブル | 代替キー非サポート |
| インデックスサイズ | 900 bytes / キー・最大 16 列 |
| テーブルあたり | 最大 10 個の代替キー定義 |
| バルク操作 | UpsertMultiple は対応・UpdateMultiple は非対応 |
| インデックス構築 | 非同期処理(Active 状態になるまで使用不可) |
業務コードに禁止文字が含まれる場合や、仮想テーブルを対象とする場合は代替キーが使えない。この点は次のセクションで扱う例外条件にも関わる。
例外①:バルク性能が要る場合
大量データを一括投入するシナリオでは、性能要件によって自前の集合演算解決が候補に上がる。
代替キーを使った UpsertMultiple は対応しており、推奨バッチサイズは標準テーブルで 100〜1,000 件/リクエスト。Microsoft の公式サンプルでは 100 件あたり約 2 秒という実測値が示されている(Use bulk operation messages、Microsoft Learn 2025)。
ただし、自前の GUID 解決(事前 Retrieve → GUID 取得 → Lookup 書込み)との直接比較数値は公式には公表されていない。「代替キーはインデックスで性能向上する」という公式の記述の範囲で判断する。
自前解決が例外として成立する条件は、集合演算を一括で走らせることで明確に性能要件を満たせると確認できる場合だ。「なんとなく速そう」で自前を選ぶのは理由にならない。
例外②:サーバーが代替キー解決口を出していない場合
もう一つの例外は、使用するツールが代替キーを通じた Lookup 書込みに対応していない場合だ。
Azure Data Factory(ADF)の Copy Data アクティビティはその典型例だ。ADF Copy Data は Dataverse の Lookup フィールドへの書込みに GUID を要求する。代替キーで直接 Lookup を解決する経路を持っていない——これはツール側の制約であり、Dataverse の設計上の問題ではない。
この場合の回避策は、Lookup アクティビティで事前に GUID を取得し、Copy Data に渡す構成になる。GUID を取得して処理する点で移送側が解決責任を持つ形になるが、それはツール側が委譲の口を提供していないための仕方ない選択だ。
代替キー解決の口がないツールを使う場合のみ、自前解決を例外として適用する。
自前解決を選んだとき:配送可搬性の喪失と向き合う
代替キー以外で自前解決を選ぶ手段は複数ある。いずれも環境ローカルな GUID を取り込むため、dev で作った定義を test/prod にそのまま配送できなくなる点は共通だ。
| 手段 | 方法 | 主な制限 |
|---|---|---|
| 事前 Retrieve(3 ステップ) | 業務コードで検索 → GUID 取得 → Lookup に GUID 書込み | API コール 2 倍。GUID は環境固有のため配送不可 |
| ADF Lookup アクティビティ | Copy Data 前に Lookup アクティビティで GUID を事前取得 | ADF Copy Data 側の制約に起因。GUID は環境固有のため配送不可 |
| Power Automate / Azure Functions 中間層 | 業務コード → GUID マッピングを中間層として構築 | 管理コスト増。GUID は環境固有のため配送不可 |
| Configuration Migration ツール | GUID 主キーを保全して環境間移行 | 設定データ専用。本番業務データには使えない |
なお、Configuration Migration ツールは GUID を保全したまま環境間移行できる特殊な仕組みだが、設定データ専用であり、通常の業務データ取込には適用できない。
自前解決を選ぶ場合、各環境で実行時に GUID を引き直すフローが必要になる。定義を一度作って配送する「build once, deploy many」の恩恵は受けられない。これが受け入れられる要件かどうかを設計時点で確認する。
判断まとめ:委譲が既定・自前が例外
ID 解決の責任配置を一枚の表に整理する。
| 観点 | 委譲(代替キー) | 自前(事前 Retrieve / 中間層) |
|---|---|---|
| 移送側が GUID を知る必要 | なし | あり |
| 配送可搬性(dev→test→prod) | 保たれる | 失われる |
| API コール数 | 1 コール | 2 コール以上 |
| 実装の手間 | 代替キー定義が必要 | 取込フローに解決ステップが必要 |
| 適合する場面 | ほぼすべての通常取込 | 大量バルク性能・ツール側制約がある場合のみ |
ツールが代替キーを使った委譲の口を提供している、かつ大量バルクの集合演算性能が要件として明確でない——この条件を満たすなら委譲が既定の選択だ。自前を選ぶのは、明確な例外条件が成立する場合に限る。
「委ねれば常に正解」ではない。代替キーの制約条件(禁止文字・仮想テーブル・UpdateMultiple 非対応等)に当たる場合は設計を見直す。例外の存在を認識した上で、既定として委譲を選ぶのがこの判断軸の骨格だ。
次の一歩
- 取込対象テーブルに代替キーが定義済みかを Power Apps メーカーポータルで確認する(テーブル → キー タブ)
- 定義がない場合、業務コード列(環境不変な値を持つ列)を選んで代替キーを追加する。インデックス構築完了(Active 状態)を待ってから取込定義に組み込む
- ADF 等ツール側の Lookup 書込み対応状況を事前に確認し、非対応なら自前解決の例外フローを設計に明示する
関連記事
- [Dataverse 代替キーで Lookup を張る:正規化手順とロードオーダー管理(normalize-at-ingestion-altkey-lookup)](リンク準備中)
- [Dataverse Upsert の突合キー選択:代替キーを安全に使う判断基準(dataverse-alternate-key-safe-upsert)](リンク準備中)
- [Dataverse データ移送と行セキュリティ連鎖:ID 解決欠落が引き起こす下流事象(dataverse-data-mover-lookup-mi-row-security)](リンク準備中)
→ 関連記事:[Power Automate と Logic Apps、3年後の保守者で決める——個人 PC で判断を持ち帰る](リンク準備中)