启用虚拟表以支持 Dataverse 事件

您可以允许虚拟实体参与异步 Dataverse 事件框架管道事件,以及 PowerAutomate Dataverse 连接器的当行被添加、修改或删除触发器。 此功能作为 Dataverse 业务事件的一部分启用。 详细信息: Microsoft Dataverse 业务事件

如果没有本文中所述的配置,大多数虚拟实体不会像其他实体一样参与事件框架管道。 由于虚拟实体不参与事件管道,因此无法针对发生的创建、更新和删除(CUD)事件注册插件步骤,尽管 CUD 事件出现在 Power Automate Dataverse 连接器中,但当人们尝试保存使用这些事件的流时,将引发错误。

这是因为虚拟实体表示存储在外部源中的数据。 Dataverse 有权以客户端身份访问该数据源,但其他系统可以随时更新该数据,而无需通过 Dataverse 事件框架。

启用此项有两个步骤:

  1. 在名为 虚拟实体元数据的表中配置数据。 当此表中的数据配置为启用它们时,一组新 API 为外部系统提供在 CUD 事件发生时通知 Dataverse 的方法。

    当有一个与虚拟表的EntityMetadata.Metadataid相关联的虚拟实体元数据行时,以下三个设置可以控制外部源是否能够通知您的虚拟表。

    当使用虚拟实体元数据的IsOnExternalCreatedEnabledIsOnExternalDeletedEnabledIsOnExternalUpdatedEnabled布尔属性单独启用时,以下绑定的操作可供外部服务调用。

    操作/消息 Description
    OnExternalCreated 包含在外部系统中创建并作为 Dataverse 虚拟表暴露的记录数据。
    OnExternalUpdated 包含在外部系统中更新并作为 Dataverse 虚拟表暴露的记录数据。
    OnExternalDeleted 包含外部系统中被删除的记录数据,该系统以虚拟表形式暴露于Dataverse。
  2. 控制数据的外部系统必须使用在虚拟实体元数据中具有数据的 API 向 Dataverse 发送经过身份验证的 HTTP 请求。 经过身份验证的服务主体帐户通常执行此调用。 详细信息:使用服务器到服务器 (S2S) 身份验证构建 Web 应用程序

    但是,可以调用 Dataverse 的任何应用程序或用户都可以发送通知 Dataverse 发生该事件所需的 http 请求。

注释

使用 OData 提供程序和非关系型数据源的虚拟实体可能允许特定插件步骤注册,例如仅限于事务外的事件。 但是,这些事件不能与 Power Automate Dataverse 连接器一起使用。 此行为没有变化。 但对于更可靠的事件通知,建议使用本主题中所述的方法。

如何为虚拟表启用通知 API

可以通过在创建者门户(make.powerapps.com/)或使用代码手动配置通知 API 来启用通知 API。

使用创建者门户手动启用

假设我们有一个具有这些属性的 Person 虚拟表, Name 属性为 new_People

new_people 虚拟表的属性。

  1. 在 Power Apps(make.powerapps.com),在解决方案中,选择 “+新建 ”,然后选择 “虚拟实体元数据”。

    在解决方案中添加一个新的 VirtualEntityMetadata。

    这将打开以下窗体:

    virtualentitymetadata 表单。

  2. 完成表单,将 “扩展实体 ID ”值设置为虚拟表的名称。 不需要启用所有这三条消息。 可以设置其中一个或多个设置,稍后返回以启用其余部分。

启用这些消息后,可以使用 “查看创建的消息以支持虚拟表”中的步骤来观察和确认添加的内容。

使用创建者门户设置托管属性

如果不希望安装托管解决方案的人员更改虚拟实体元数据行为,则应设置托管属性以防止使用以下步骤。

  1. 在解决方案中,选择虚拟实体元数据并选择省略号(...),然后选择 “托管属性”。

    导航到托管属性。

  2. 在“托管属性”窗格中,取消选择 “允许自定义项 ”,然后按 “完成”。

    取消选择“允许自定义”。

    在托管解决方案中包含虚拟实体元数据记录之前,此设置不会执行任何作。

使用代码启用

你可能希望自动为虚拟实体创建虚拟实体元数据。

VirtualEntityMetadata 表具有以下可设置的列:

架构名称
逻辑名称
显示名称 类型 Description
ExtensionOfRecordId
extensionofrecordid
虚拟实体 查找 这些设置所针对的虚拟实体的名称。
IsCustomizable
iscustomiable
可自定义 ManagedProperty 控制在托管解决方案中包括时是否可以更改或删除虚拟实体元数据。
IsOnExternalCreatedEnabled
isonexternalcreatedenabled
启用外部创建消息 布尔 允许消息发送有关在外部数据源中创建的新记录的信息。
IsOnExternalDeletedEnabled
isonexternaldeletedenabled
启用外部删除消息 布尔 使消息能够发送有关外部数据源中已删除记录的信息。
IsOnExternalUpdatedEnabled
isonexternalupdatedenabled
启用外部更新消息 布尔 使消息能够发送有关外部数据源中更新的记录的信息。
Name
name
Name String 设置的名称。
VirtualEntityMetadataId
virtualentitymetadataid
VirtualEntityMetadata Uniqueidentifier 实体实例的唯一标识符

创建这些类型的解决方案组件时,建议将 IsCustomizable 托管属性设置为 false “,除非希望允许安装托管解决方案的人员能够更改这些设置。

我们还建议在创建虚拟实体元数据记录时,将其添加到特定的解决方案中。 在下面的两个示例中,你将看到如何通过请求传递 Solution.UniqueName 以创建记录。

使用 Web API

使用 Web API 时,第一个任务是获取 MetadataId 虚拟表。 以下示例返回名为 new_people 的虚拟实体的 MetadataId

请求:

GET [Organization Uri]/api/data/v9.1/EntityDefinitions(LogicalName='new_people')?$select=MetadataId HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
Accept: application/json
Authorization: Bearer [REDACTED]

响应:

HTTP/1.1 200 OK

{
    "@odata.context": "[Organization Uri]/api/data/v9.1/$metadata#EntityDefinitions(MetadataId)/$entity",
    "MetadataId": "b198e6f3-3dd6-4c0b-9570-702f0c10d577"
}

随后创建虚拟实体元数据记录,并使用第一步检索到的 MetadataId 将其关联至 Entity 实体类型。

注意使用设置为 Solution.UniqueName 值的 MSCRM.SolutionUniqueName 标头。 在创建解决方案时,这会将虚拟实体元数据记录添加到解决方案中。 详细信息: HTTP 标头

请求:

POST [Organization Uri]/api/data/v9.1/virtualentitymetadatas HTTP/1.1
MSCRM.SolutionUniqueName: YourSolutionUniqueName
OData-MaxVersion: 4.0
OData-Version: 4.0
Accept: application/json
Authorization: Bearer [REDACTED]
Content-Type: application/json; charset=utf-8

{
  "@odata.type": "Microsoft.Dynamics.CRM.virtualentitymetadata",
  "name": "Person Virtual Metadata",
  "iscustomizable": {
    "@odata.type": "Microsoft.Dynamics.CRM.BooleanManagedProperty",
    "Value": false,
    "CanBeChanged": false
  },
  "isonexternalcreatedenabled": true,
  "isonexternaldeletedenabled": true,
  "isonexternalupdatedenabled": true,
  "extensionofrecordid@odata.bind": "entities(b198e6f3-3dd6-4c0b-9570-702f0c10d577)"
}

响应:

HTTP/1.1 204 No Content

使用 SDK for .NET

无论采用早期绑定还是后期绑定类型,首要任务都是检索表的 MetadataId,两种情况下的检索方式相同。 本例中,针对名为 new_people 的虚拟表使用 CrmServiceClient。 或者,可以使用该 ServiceClient 类。

var service = new CrmServiceClient(conn);
// var service = new ServiceClient(conn);

var retrieveEntityRequest = new RetrieveEntityRequest
{
    LogicalName = "new_people",
    EntityFilters = EntityFilters.Entity
};

var retrieveEntityResponse = (RetrieveEntityResponse)service.Execute(retrieveEntityRequest);

var entityId = retrieveEntityResponse.EntityMetadata.MetadataId;

使用早期绑定类型

采用早期绑定类型时,可使用通过 Power Platform CLI pac modelbuilder build 命令生成的 VirtualEntityMetadata 类。 更多信息:使用 .NET SDK 进行晚期绑定与早期绑定编程

var virtualEntityMetadata = new VirtualEntityMetadata
{
    Name = "Person Virtual Metadata",
    ExtensionOfRecordId = new EntityReference("entity", entityId.Value),
    IsCustomizable = new BooleanManagedProperty(false),
    IsOnExternalCreatedEnabled = true,
    IsOnExternalDeletedEnabled = true,
    IsOnExternalUpdatedEnabled = true,
};

使用晚期绑定类型

通过晚期绑定类型实例化虚拟实体元数据实例有两种等效方式:

var virtualEntityMetadata = new Entity("virtualentitymetadata");
virtualEntityMetadata["name"] = "Person Virtual Metadata";
virtualEntityMetadata["extensionofrecordid"] = new EntityReference("entity", entityId.Value);
virtualEntityMetadata["iscustomizable"] = new BooleanManagedProperty(false);
virtualEntityMetadata["isonexternalcreatedenabled"] = true;
virtualEntityMetadata["isonexternaldeletedenabled"] = true;
virtualEntityMetadata["isonexternalupdatedenabled"] = true;

或者:

  var virtualEntityMetadata = new Entity("virtualentitymetadata") { 
      Attributes = new AttributeCollection {
          { "name","Person Virtual Metadata" },
          { "extensionofrecordid", new EntityReference("entity", entityId.Value)},
          { "iscustomizable",new BooleanManagedProperty(false)},
          { "isonexternalcreatedenabled",true },
          { "isonexternaldeletedenabled",true },
          { "isonexternalupdatedenabled",true}
      }            
  };

创建记录

创建记录时,请使用 CreateRequest 类 而不是 IOrganizationService.Create 方法 ,以便你可以包含 SolutionUniqueName 可选参数,该参数会在创建记录时将记录添加到解决方案中。 详细信息: 使用请求传递可选参数

var createRequest = new CreateRequest
{
    Target = virtualEntityMetadata
};
createRequest["SolutionUniqueName"] = "YourSolutionUniqueName";

service.Execute(createRequest);

查看为支持虚拟数据表而创建的消息

验证启用的消息是否存在的一种简单方法是检查 Web API $metadata服务文档。

可以在浏览器中进行操作。 使用组织的 URL,在浏览器中键入以下内容:

[Organization Uri]/api/data/v9.2/$metadata

这是一个大型 XML 文档,但你可以搜索 OnExternalCreated 并查找动作的定义,在本例中,new_people 是虚拟表。

<Action Name="OnExternalCreated" IsBound="true">
 <Parameter Name="entityset" Type="Collection(mscrm.new_people)" Nullable="false"/>
 <Parameter Name="Target" Type="mscrm.crmbaseentity" Nullable="false"/>
</Action>

可见此为绑定至 new_people 实体集的 OData 操作。 您将发现针对 OnExternalDeletedOnExternalUpdated 的类似操作:

<Action Name="OnExternalDeleted" IsBound="true">
 <Parameter Name="entityset" Type="Collection(mscrm.new_people)" Nullable="false"/>
<Parameter Name="Target" Type="mscrm.crmbaseentity" Nullable="false"/>
</Action>
<Action Name="OnExternalUpdated" IsBound="true">
 <Parameter Name="entityset" Type="Collection(mscrm.new_people)" Nullable="false"/>
 <Parameter Name="Target" Type="mscrm.crmbaseentity" Nullable="false"/>
</Action>

使用插件注册工具查看消息

使用插件注册工具注册插件步骤时,你将找到这些消息。

在新建人员实体上注册 OnExternalCreated 消息的插件步骤。

使用消息通知 Dataverse 变更

若要通知 Dataverse 更改,必须调用相应的 API。 可以使用 Dataverse Web API 或用于 .NET 的 SDK。

在使用这些消息之前,可能需要使用 “查看创建的消息以支持虚拟表 ”中所述的过程来确认它们是否存在。

使用 Web API

由于这些 API 是表集合绑定的 OData 操作,可以遵循此处所述的模式:使用绑定到表集合的 Web API 操作> 绑定操作> 绑定到表集合的操作。 下面是一些展示 new_people 虚拟表用法的示例。

如果调用系统知道 ID 值,应始终包含它。 使用 目标 参数传递的实体实例必须具有相应的 @odata.type 批注属性集来定义实体的类型。 如果不包括这一项,将返回错误。

这些调用应始终返回 204: No Content

OnExternalCreated

对于此作,值应包括创建记录时设置的所有属性。

POST [Organization Uri]/api/data/v9.1/new_peoples/Microsoft.Dynamics.CRM.OnExternalCreated HTTP/1.1
Authorization: Bearer [REDACTED]
Content-Type: application/json
 
{
    "Target": {
        "@odata.type": "Microsoft.Dynamics.CRM.new_people",
        "new_name": "John",
        "new_age": 23,
        "new_lastname": "Doe",
        "new_peopleid": "f6f5896b-bf08-455c-9bd3-526760cb3685"
    }
}

OnExternalUpdated

对于此操作,仅应包括已更改的属性项。

POST [Organization Uri]/api/data/v9.1/new_peoples/Microsoft.Dynamics.CRM.OnExternalUpdated HTTP/1.1
Authorization: Bearer [REDACTED]
Content-Type: application/json
 
{
    "Target": {
        "@odata.type": "Microsoft.Dynamics.CRM.new_people",
        "new_age": 24,
        "new_peopleid": "f6f5896b-bf08-455c-9bd3-526760cb3685"
        }
}

OnExternalDeleted

对于此操作而言,只需要记录的唯一标识符。

POST [Organization Uri]/api/data/v9.1/new_peoples/Microsoft.Dynamics.CRM.OnExternalDeleted HTTP/1.1
Authorization: Bearer [REDACTED]
Content-Type: application/json
{
    "Target": {
        "@odata.type": "Microsoft.Dynamics.CRM.new_people",
        "new_peopleid": "f6f5896b-bf08-455c-9bd3-526760cb3685"
        }
}

使用 .NET 的 SDK

使用适用于 .NET 的 SDK 时,可以使用早期或后期绑定类型。 更多信息:使用 .NET SDK 进行晚期绑定与早期绑定编程

早期绑定类型

此示例使用具有早期绑定类型的 CrmServiceClient ,但 ServiceClient 也可以使用。

var service = new CrmServiceClient(conn);
// var service = new ServiceClient(conn);

//OnExternalCreated
var createPerson = new new_people
{
    new_peopleId = new Guid("f6f5896b-bf08-455c-9bd3-526760cb3685"),
    new_name = "John",
    new_Age = 23,
    new_LastName = "Doe"
};


var createRequest = new OnExternalCreatedRequest
{
    Target = createPerson
};

service.Execute(createRequest);

//OnExternalUpdated
var updatePerson = new new_people
{
    new_peopleId = new Guid("f6f5896b-bf08-455c-9bd3-526760cb3685"),
    new_Age = 24
};


var updateRequest = new OnExternalUpdatedRequest
{
    Target = updatePerson
};

service.Execute(updateRequest);

//OnExternalDeleted
var deletePerson = new new_people
{
    new_peopleId = new Guid("f6f5896b-bf08-455c-9bd3-526760cb3685")
};


var deleteRequest = new OnExternalDeletedRequest
{
    Target = deletePerson
};

后期绑定类型

此示例使用 CrmServiceClient 配合晚期绑定类型,但也可使用 ServiceClient

var service = new CrmServiceClient(conn);
// var service = new ServiceClient(conn);

  //OnExternalCreated
  Entity createPerson = new Entity("new_people");
  createPerson["new_peopleid"] = new Guid("f6f5896b-bf08-455c-9bd3-526760cb3685");
  createPerson["new_name"] = "John";
  createPerson["new_age"] = 23;
  createPerson["new_lastname"] = "Doe";

  
  var orgCreateRequest = new OrganizationRequest("OnExternalCreated");
  orgCreateRequest["Target"] = createPerson;

  service.Execute(orgCreateRequest);

  //OnExternalUpdated
  Entity updatePerson = new Entity("new_people");
  updatePerson["new_peopleid"] = new Guid("f6f5896b-bf08-455c-9bd3-526760cb3685");
  updatePerson["new_age"] = 24;

  
  var orgUpdateRequest = new OrganizationRequest("OnExternalUpdated");
  orgUpdateRequest["Target"] = updatePerson;

  service.Execute(orgUpdateRequest);

  //OnExternalDeleted
  Entity deletePerson = new Entity("new_people");
  deletePerson["new_peopleid"] = new Guid("f6f5896b-bf08-455c-9bd3-526760cb3685");

  
  var orgDeleteRequest = new OrganizationRequest("OnExternalDeleted");
  orgDeleteRequest["Target"] = deletePerson;

  service.Execute(orgDeleteRequest);

另请参阅

事件框架
Microsoft Dataverse 业务事件
虚拟表(实体)入门