次の方法で共有


スキーマ定義のクエリ

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

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

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

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

スキーマ定義を取得するクエリを作成する場合、 RetrieveMetadataChanges メッセージは、複数のテーブル定義にまたがる単一の要求を定義し、派生型の詳細を返し、時間の経過と同時にキャッシュを管理する利点を提供します。

次の表は、スキーマ定義を取得する他の方法をまとめたものですが、一定期間キャッシュを管理する機能はありません。

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

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

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

制限事項: 必要な特定のプロパティを選択することはできません。
RetrieveRelationship 任意の 1 つのリレーションシップの完全な定義を取得できます。
参照: テーブルのリレーションシップを取得する

制限事項: 必要な特定のプロパティを選択することはできません。
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 が true であるすべての列定義を展開します。

次の例では、 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を使用して、RetrieveMetadataChangesQuery プロパティを設定します。

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

プロパティ タイプ Description
Properties MetadataPropertiesExpression PropertyNamesを、返すプロパティ名の一覧に設定します。 または、 AllProperties を true に設定して、すべてのプロパティを返すことができます。 アイテムが含まれている場合は、 MetadataIdLogicalName、または HasChanged プロパティ名を追加する必要はありません。 これらのプロパティは常に含まれます。
Criteria MetadataFilterExpression MetadataFilterExpression を使用して返されるデータの制限を参照してください
AttributeQuery AttributeQueryExpression EntityQueryExpressionと同じパターンに従います。 AttributeQueryExpression には、返す列定義を制御するための PropertiesCriteria もあります。

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

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

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

Query パラメーターは省略可能であるため、フィルターなしでRetrieveMetadataChangesを使用できますが、これは非常にコストの高い操作である RetrieveAllEntities を使用するのと同じです。

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

EntityQueryExpression、AttributeQueryExpression、RelationshipQueryExpression、EntityKeyQueryExpressionCriteriaプロパティには MetadataFilterExpression使用します。

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

プロパティ タイプ Description
FilterOperator LogicalOperator ConditionsまたはAndのいずれかで、Orの評価方法を制御します。
Conditions DataCollection<MetadataConditionExpression> 評価する条件のコレクション。 MetadataConditionExpression を使用した条件の設定を参照してください
Filters DataCollection<MetadataFilterExpression> より複雑なクエリに適用するその他のフィルター。

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

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

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

プロパティ タイプ Description
ConditionOperator MetadataConditionOperator Value プロパティに適用する比較の種類について説明します。
PropertyName 文字列 評価するプロパティの名前
Value オブジェクト 比較する値 (または値)。

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

MetadataConditionOperator 列挙値

MetadataConditionOperator列挙型には、次のメンバーがあります。

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

返されたデータを処理する

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

プロパティ タイプ Description
EntityMetadata EntityMetadataCollection 要求されたテーブル定義。 データのクエリを実行するとき、またはキャッシュを初期化するときに、この値を RetrieveAllEntities メッセージからの応答と同じように扱うことができます。 特定の列、リレーションシップ、または代替キー定義にアクセスする場合は、それらを含むテーブル定義を返す必要があります。
ServerVersionStamp string 取得したメタデータのタイムスタンプ識別子。 スキーマ定義のキャッシュを管理する場合は、後続の要求でこの値を ClientVersionStamp プロパティとして使用して、前の要求以降の変更のみが返されるようにします。
DeletedMetadata DeletedMetadataCollection 前の要求以降に削除されたアイテムのデータ。 この値には、RetrieveMetadataChangesパラメーターとClientVersionStamp パラメーターを使用して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#)
SDK for .NET: Microsoft Dataverse のテーブル定義
Web API を使用したテーブル定義のクエリ