次の方法で共有


方法: Dataverse テーブルのメタデータを取得する (プレビュー)

テーブル メタデータには、Dataverse のテーブルに適用されるカスタマイズが含まれています。 メタデータには、組織が複数の言語をサポートしている場合にローカライズされたラベルも含まれます。 コード アプリでメタデータを使用すると、コードを変更しなくても、アプリがカスタマイズやローカライズの変更に適応できることを意味します。

getMetadata関数を使用して、実行時に Dataverse テーブル (エンティティ) メタデータを取得します。 この関数は、 Web API を使用したクエリ テーブル定義 で説明されている機能を軽くラップし、エンティティ定義、属性、およびリレーションシップへの厳密に型指定されたアクセスを提供します。

getMetadata シグネチャ

getMetadata関数では、返されるデータを定義するためにGetEntityMetadataOptionsのインスタンスが必要です。

AccountsService.getMetadata(
  options?: GetEntityMetadataOptions<Account>
): Promise<IOperationResult<Partial<EntityMetadata>>>

を呼び出す前に、「Dataverse への接続getMetadataする」の手順に従って Power SDK を初期化し、サービス ファイルをインポートする必要があります。

GetEntityMetadataOptions パラメーター

getMetadataoptions パラメーターを設定して、取得するメタデータを選択します。

interface GetEntityMetadataOptions {
  metadata?: Array<String>;
  schema?: {
    columns?: "all" | Array<String>;
    oneToMany?: boolean;
    manyToOne?: boolean;
    manyToMany?: boolean;
  };
}
  • metadata: エンティティレベルのプロパティの配列で、たとえば["Privileges","DisplayName","IsCustomizable"]などをフェッチします。 クエリ可能なテーブル プロパティの完全な一覧については、 EntityMetadata プロパティを参照してください。

  • schema:

    • columns: 列 (属性) メタデータの取得 - "all" または列論理名の配列 ( ["name","telephone1","createdon"]など)。 クエリ可能な属性プロパティの完全な一覧については、 AttributeMetadata プロパティを参照してください。

      AttributeMetadataに含まれていないプロパティを指定することはできません。 派生型によって定義されたプロパティは使用できません。 つまり、選択 (選択リスト) 列オプションなどのプロパティは派生型によって定義されているため、アクセスできません。

    • oneToManymanyToOnemanyToMany: リレーションシップ メタデータを含むようにブール値を設定します

応答には、Attributes 型のという名前の配列、OneToManyRelationships 型のManyToOneRelationships 型の、および要求されたときに ManyToManyRelationships 型のが含まれます。

例示

次の例は、テーブル メタデータを取得して使用する一般的な方法を示しています。

すべての列のユーザーローカライズされたラベルを取得する

ユーザーの言語で表示名を取得します。 これらのラベルを使用して、フォーム ラベル、テーブル ヘッダー、およびアクセシビリティ テキストを作成します。

async function getColumnDisplayNames() {
// Request all column metadata
const { data } = await AccountsService.getMetadata({
   schema: { columns: 'all' }
});

const columnDisplayNames: Record<string, string> = {};
if (data.Attributes) {
   for (const attr of data.Attributes) {
      const label = attr.DisplayName?.UserLocalizedLabel?.Label;
      if (label) {
      columnDisplayNames[attr.LogicalName] = label;
      }
   }
}

console.log(columnDisplayNames);
// Output: { "accountid": "Account", "name": "Account Name", ... }
return columnDisplayNames;
}

フォーム検証に必要なフィールドを識別する

ハード コーディングではなく、メタデータに基づいてクライアント側の検証規則を構築するためにフォームに必要な属性を検索します。

async function getRequiredFields() {
const { data } = await AccountsService.getMetadata({
   schema: { columns: 'all' }
});
if (!data.Attributes) return [];

// Filter attributes that are required for forms
const requiredColumns = data.Attributes
   .filter(attr => attr.IsRequiredForForm)
   .map(attr => ({
      logicalName: attr.LogicalName,
      displayName: attr.DisplayName?.UserLocalizedLabel?.Label,
      attributeType: attr.AttributeTypeName?.Value
   }));

console.log('Required fields:', requiredColumns);
// Output: [
//   { logicalName: "name", displayName: "Account Name", attributeType: "StringType" },
//   { logicalName: "ownerid", displayName: "Owner", attributeType: "OwnerType" }
// ]

return requiredColumns;
}

クライアント側検証のマップ列の種類

検証コントロールと UI コントロールに通知する属性の型を取得します。 適切な UI コントロール (日付の選択、支払い、選択など) を選択し、値を一貫して検証します。

async function getColumnTypes() {
  const { data } = await AccountsService.getMetadata({
    schema: { columns: 'all' }
  });

  if (!data.Attributes) return [];

  // Map attributes to their types for validation
  const columnTypes = data.Attributes.map(attr => ({
    logicalName: attr.LogicalName,
    attributeType: attr.AttributeTypeName?.Value,
  }));

  console.log('Column types:', columnTypes);
  // Output: [
  //   {
  //     logicalName: "accountid",
  //     attributeType: "UniqueidentifierType",
  //   },
  //   {
  //     logicalName: "name",
  //     attributeType: "StringType",
  //   },
  //   {
  //     logicalName: "revenue",
  //     attributeType: "MoneyType",
  //   },
  //   {
  //     logicalName: "createdon",
  //     attributeType: "DateTimeType",
  //   }
  // ]
  
  return columnTypes;
}

ルックアップ リレーションシップを検出する (多対一)

リレーションシップに基づいてルックアップ UI とナビゲーションを動的に構築するために、他のテーブルを指すルックアップ フィールドを検索します。

async function getLookupRelationships() {
  const { data } = await AccountsService.getMetadata({
    metadata: ['LogicalName', 'DisplayName'],
    schema: { 
      manyToOne: true  // Get lookup relationships
    }
  });

  if (!data.ManyToOneRelationships) return [];

  // Get all lookup fields pointing to other tables
  const lookupRelationships = data.ManyToOneRelationships.map(rel => ({
    lookupField: rel.ReferencingAttribute,
    relatedTable: rel.ReferencedEntity,
    relatedTableAttribute: rel.ReferencedAttribute,
    relationshipName: rel.SchemaName,
  }));

  console.log('Lookup relationships:', lookupRelationships);
  // Output: [
  //   {
  //     lookupField: "primarycontactid",
  //     relatedTable: "contact",
  //     relatedTableAttribute: "contactid",
  //     relationshipName: "account_primary_contact",
  //   },
  //   {
  //     lookupField: "ownerid",
  //     relatedTable: "systemuser",
  //     relatedTableAttribute: "systemuserid",
  //     relationshipName: "owner_accounts",
  //   }
  // ]
  
  return lookupRelationships;

ベスト プラクティス

  • キャッシュ メタデータ : メタデータの呼び出しが多い場合があります。 アプリの開始時またはセッションごとにキャッシュします。
  • 必要なものだけを要求 する: パフォーマンスを高めるには、 "all" よりも列リストを優先します。
  • 防御アクセス : 入れ子になった値にアクセスする前に、プロパティの存在を確認します (例: DisplayName?.UserLocalizedLabel?.Label)。
  • TypeScript 型を使用する : より安全なコードを得るための Dataverse Web API から生成された型に依存します。