スキーマ定義のクエリ

Dataverse を使用して構築されたアプリケーションは、スキーマ定義の変更に適応可能である必要があります。 新しいテーブル、列、リレーションシップ、およびラベルは、構成で、またはソリューションのインポートによって追加または変更できます。 アプリケーションはこれらの変更に対応可能である必要があるため、起動時にスキーマ定義の取得に依存することがよくあります。 ただし、Dataverse 組織のスキーマを記述するデータの総量が非常に大きくなる可能性があります。 必要なデータだけを取得する方法を知る必要があります。

RetrieveMetadataChanges メッセージには次の 2 つの機能があります。

  1. クエリ: 単一のクエリを作成して、必要なスキーマ データのみを取得します。 この記事では、クエリの作成に焦点を当てます。
  2. キャッシュ管理: アプリでスキーマ定義データをキャッシュする場合は、RetrieveMetadataChanges を使用して最後のクエリ以降の変更のみを効率的に取得します。 これらの変更に関する情報を使用して、キャッシュ内のアイテムを追加または削除します。 キャッシュにより、アプリケーションの起動時間が大幅に短縮される可能性があります。 キャッシュ管理については、スキーマ データのキャッシュで説明します。

スキーマ定義を取得するための他のオプションを評価する

スキーマ定義を取得するクエリを作成する場合、RetrieveMetadataChanges メッセージには、複数のテーブル定義にまたがる単一の要求を定義し、派生型の詳細を返し、長期的なキャッシュを管理できるという利点があります。

次の表は、スキーマ定義を取得できる他の方法をまとめたものですが、それらの方法のいずれも、経時的にキャッシュを管理する機能はありません。

Message 説明と制限
RetrieveAllEntities 必要に応じて、すべての列、特権、およびリレーションシップを含む、すべてのテーブルのデータを取得します。
参照: RetrieveAllEntitiesRequest クラスと RetrieveAllEntitiesResponse クラス。

制限事項: EntityFilters パラメーターを使用して一部の部分を除外することはできますが、これは非常にコストのかかる操作です。
RetrieveEntity 必要に応じて、すべての列、権限、およびリレーションシップを含む単一のテーブル定義を取得できます。
参照: テーブルを取得して更新する

制限事項: EntityFilters パラメーターを使用して一部のデータを除外することはできますが、必要な特定のプロパティを選択することはできず、それでもコストのかかる操作です。
RetrieveAttribute 単一の属性の定義を完全に取得できます。
参照: 列を取得する

制限: 必要な特定のプロパティを選択できません。
RetrieveRelationship 単一のリレーションシップの定義を完全に取得できます。
テーブル関係の取得を参照してください

制限: 必要な特定のプロパティを選択できません。
RetrieveAllOptionSets 組織で定義されたすべてのグローバルな選択肢に関する情報を取得できます。
参照: グローバルな選択肢の挿入、更新、削除、および順序付け

制限: 列内でローカルにのみ定義されている選択肢は含まれません。
RetrieveEntityKey 特定のテーブルの代替キーの定義を取得できます。
参照: 代替キーの取得および削除

基本的な RetrieveMetadataChanges の例

RetrieveMetadataChanges で可能なことの簡単な例として、Web API と EntityDefinitions エンティティ セットで可能なことを比較します。

Web API を使用すると、次のようなクエリを作成できます。

GET [Organization URI]/api/data/v9.2/EntityDefinitions?$select=SchemaName&$filter=LogicalName eq 'account' or LogicalName eq 'contact'&$expand=Attributes($select=LogicalName;$filter=IsValidForCreate eq true)

このクエリは、取引先テーブル定義と連絡先テーブル定義の両方からデータを返し、IsValidForCreate が真であるすべての列定義を展開します。

次の例は、RetrieveMetadataChanges を使用して同じクエリを作成する方法を示しています。

/// <summary>
/// Get the SchemaName for the account and contact tables together with
/// the LogicalName of any attributes which are valid for create
/// </summary>
/// <param name="service"></param>
static void SimpleRetrieveMetadataChangesExample(IOrganizationService service) {

    var query = new EntityQueryExpression
    {
        Properties = new MetadataPropertiesExpression("SchemaName", "Attributes"),
        Criteria = new MetadataFilterExpression(filterOperator: LogicalOperator.Or)
        {
            Conditions = {
                {
                    new MetadataConditionExpression(
                        propertyName:"LogicalName",
                        conditionOperator: MetadataConditionOperator.Equals,
                        value:"account")
                },
                {
                    new MetadataConditionExpression(
                        propertyName:"LogicalName",
                        conditionOperator: MetadataConditionOperator.Equals,
                        value:"contact")
                }
            }, 
        },
        AttributeQuery = new AttributeQueryExpression
        {
            Properties = new MetadataPropertiesExpression("LogicalName"),
            Criteria = new MetadataFilterExpression(filterOperator: LogicalOperator.And)
            {
                Conditions = {
                    {
                        new MetadataConditionExpression(
                        propertyName:"IsValidForCreate",
                        conditionOperator: MetadataConditionOperator.Equals,
                        value:true)
                    }
                }
            }            
        },
        LabelQuery = new LabelQueryExpression { 
             FilterLanguages = {
                { 1033 }
            } 
        }
        
    };

    var request = new RetrieveMetadataChangesRequest
    {
        Query = query
    };

    var response = (RetrieveMetadataChangesResponse)service.Execute(request);

    response.EntityMetadata.ToList().ForEach(em => {

        Console.WriteLine($"Entity SchemaName:{em.SchemaName}");
        em.Attributes.ToList().ForEach(a => {
            Console.WriteLine($"\tAttribute LogicalName:{a.LogicalName}");
        });
    });
}

出力:

Entity SchemaName:Account
        Attribute LogicalName:emailaddress3
        Attribute LogicalName:emailaddress1
        Attribute LogicalName:address1_city
    <List truncated for brevity>
Entity SchemaName:Contact
        Attribute LogicalName:contactid
        Attribute LogicalName:emailaddress3
        Attribute LogicalName:emailaddress2
    <List truncated for brevity>

EntityQueryExpression を使用してクエリを作成する

EntityQueryExpression を使用して RetrieveMetadataChanges Query プロパティを設定します。

EntityQueryExpression には以下のプロパティがあります。

Property タイプ 説明設定
Properties MetadataPropertiesExpression PropertyNames に、返すプロパティ名のリストを設定します。 または、AllProperties を true に設定して、すべてのプロパティを返すことができます。 それらが含まれる項目については、MetadataIdLogicalName、または HasChanged プロパティ名を追加する必要はありません。 これらのプロパティは常に含まれます。
Criteria MetadataFilterExpression 参照: MetadataFilterExpression を使用して返されるデータを制限する
AttributeQuery AttributeQueryExpression EntityQueryExpression と同じパターンに従います。 AttributeQueryExpression には PropertiesCriteria も含まれ、返す列定義を制御します。

: AttributeQuery を使用するときは、AttributesEntityQueryExpression 向けに要求された Properties のいずれかである必要があります。
RelationshipQuery RelationshipQueryExpression EntityQueryExpression と同じパターンに従います。 RelationshipQueryExpression には PropertiesCriteria も含まれ、返すリレーションシップ定義を制御します。

: RelationshipQueryOneToManyRelationshipsManyToOneRelationships または ManyToManyRelationships を使用するときは、PropertiesEntityQueryExpression 向けに要求されたののいずれかである必要があります。
KeyQuery EntityKeyQueryExpression EntityQueryExpression と同じパターンに従います。 EntityKeyQueryExpression には PropertiesCriteria も含まれ、返す代替キー定義を制御します。

: KeyQuery を使用するときは、KeysEntityQueryExpression 向けに要求された Properties のいずれかである必要があります。
LabelQuery LabelQueryExpression FilterLanguages プロパティを使用して、返される言語を制限します。 組織に多くの言語がプロビジョニングされている場合、すべての言語のラベルを受け取ることになり、返されるデータが大幅に増加する可能性があります。 アプリが個人ユーザー向けの場合は、ユーザーの優先する LCID 言語コード を含める必要があります。 参照: ユーザーの優先する言語コードを取得する

注意

Query パラメータはオプションなので、フィルターなしで RetrieveMetadataChanges を使用できますが、これは RetrieveAllEntities 使用するのと同じで、非常にコストのかかる操作です。

MetadataFilterExpression を使用して返されるデータを制限する

EntityQueryExpressionAttributeQueryExpressionRelationshipQueryExpression、および EntityKeyQueryExpressionCriteria プロパティに MetadataFilterExpression を使用します。

MetadataFilterExpression には、次のプロパティがあります。

Property タイプ 説明設定
FilterOperator LogicalOperator ConditionsAnd または Or か評価する方法を制御します。
Conditions DataCollection<MetadataConditionExpression> 評価する条件のコレクション。 参照: MetadataConditionExpression を使用して条件を設定する
Filters DataCollection<MetadataFilterExpression> より複雑なクエリに適用するフィルターが増えました。

MetadataConditionExpression を使用して条件を設定する

MetadataFilterExpression Conditions プロパティに MetadataConditionExpression を使用します。

MetadataConditionExpression には、次のプロパティがあります。

Property タイプ 説明設定
ConditionOperator MetadataConditionOperator Value プロパティに適用する比較の型を記述します。
PropertyName string 評価するプロパティの名前
Value オブジェクト 比較する値 (1 つまたは複数)。

一般に、MetadataFilterExpression の単純なデータ型、列挙型、BooleanManagedProperty、または AttributeRequiredLevelManagedProperty を示すプロパティのみを使用できます。 コレクションまたはラベルのプロパティには条件を設定できません。 BooleanManagedProperty または AttributeRequiredLevelManagedProperty を指定すると、Value プロパティだけが評価されます。 AttributeMetadata.SourceType プロパティ でのフィルタリングはサポートされていません。

MetadataConditionOperator 列挙値

MetadataConditionOperator 列挙には次のメンバーが含まれます。

Field Description
Equals 値が等しいかどうかが比較されます。
NotEquals 2 つの値は等しくありません。
In 値は値のリストに存在します。
NotIn 指定された値がリスト内の値と一致しません。
GreaterThan 値が比較する値より大きい。
LessThan 値が比較する値より小さい。

プロセス データを返します

RetrieveMetadataChangesResponse には、次のプロパティがあります。

Property タイプ 説明設定
EntityMetadata EntityMetadataCollection テーブル定義を要求します。 データをクエリするとき、またはキャッシュを初期化するとき、この値は RetrieveAllEntities メッセージからの応答と同じように扱うことができます。 特定の列、リレーションシップ、または 代替キーの定義にアクセスする場合は、それらを含むテーブル定義を返す必要があります。
ServerVersionStamp string メタデータのタイムスタンプ識別子を取得します。 スキーマ定義のキャッシュを管理する場合は、この値を後続の要求の ClientVersionStamp プロパティとして使用して、前の要求以降の変更のみが返されるようにします。
DeletedMetadata DeletedMetadataCollection 前の要求以降に削除された項目のデータ。 この値には、RetrieveMetadataChangesClientVersionStamp および DeletedMetadataFilters パラメーターとともに送信される場合のデータのみが含まれます。 詳細については、スキーマ データのキャッシュを参照してください

ユーザーの優先する言語コードを取得する

次の例は、ユーザーの優先 LCID 言語コードを取得する方法を示しています。

ユーザーの優先する言語は、UserSettings.UILanguageId 列から取得できます。

static int? RetrieveUserUILanguageCode(IOrganizationService service)
{
   // To get the current user's systemuserid
   var whoIAm = (WhoAmIResponse)service.Execute(new WhoAmIRequest());

   var query = new QueryExpression("usersettings")
   {
         ColumnSet = new ColumnSet("uilanguageid", "systemuserid"),
         Criteria = new FilterExpression
         {
            Conditions = {
                  {
                     new ConditionExpression(
                        attributeName:"systemuserid",
                        conditionOperator:ConditionOperator.Equal,
                        value: whoIAm.UserId)
                  }
            }
         },
         TopCount = 1
   };

   EntityCollection userSettings = service.RetrieveMultiple(query: query);
   if (userSettings.Entities.Count > 0)
   {
         return (int)userSettings.Entities[0]["uilanguageid"];
   }
   return null;
}

参照

キャッシュ スキーマ データ
Web API クエリ スキーマ定義と変更の検出のサンプル (C#)
SDK for .NET クエリ スキーマ定義と変更の検出のサンプル (C#)
.NET 用 SDK: Microsoft Dataverse のテーブル定義
Web API を使用してテーブル定義をクエリ

注意

ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)

この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。