通过


使用更改跟踪将数据与外部系统同步

Microsoft Dataverse 中的更改跟踪功能提供了一种通过检测自最初提取或上次同步数据以来的数据更改来有效同步数据的方法。 本文讨论如何激活表并获取修改信息。

为表启用更改跟踪

在检索表的更改之前,请确保为该表启用更改跟踪。

可以使用 Power Apps 检查此功能是否已启用或启用此功能。 选择数据>表格和特定表。 在高级选项下,您会找到跟踪更改属性。

通过将 EntityMetadata.ChangeTrackingEnabled 属性 设置为 True,以编程方式设置此属性。

注释

为表启用更改跟踪后,无法将其禁用。

有关如何使用 Power Apps 的详细信息,请参阅 使用 Power Apps 创建和编辑表

若要使用 Dataverse Web API 检查是否为表启用了更改跟踪,请使用以下方法之一:

  1. 使用以下 GET 请求查询 EntityDefinitions

    GET [Organization URI]/api/data/v9.2/EntityDefinitions?$select=SchemaName&$filter=ChangeTrackingEnabled eq true
    

    某些系统表已启用变更跟踪功能,例如审核。 若要查看完整列表,请使用以下查询:

    GET [Organization URI]/api/data/v9.2/EntityDefinitions?$filter=ChangeTrackingEnabled eq true and IsCustomEntity eq false&$select=LogicalName
    

    有关详细信息,请参阅 使用 Web API 的查询表定义

  2. 检查 Web API $metadata 服务文档。 批注 Org.OData.Capabilities.V1.ChangeTracking 是为已启用更改跟踪的实体集设置的。

    若要查看 Web API CDSL 服务文档中的注释,请使用以下 Web API 查询:

    GET [Organization URI]/api/data/v9.2/$metadata?annotations=true
    

    代表已启用更改跟踪的表的实体集带有此注释:

    <Annotation Term="Org.OData.Capabilities.V1.ChangeTracking">
       <Record>
             <PropertyValue Property="Supported" Bool="true" />
       </Record>
    </Annotation>
    

    有关详细信息,请参阅 元数据注释

不符合更改跟踪条件的表

无法为某些表启用更改跟踪。 若要检查表是否有资格进行更改跟踪,请检查 EntityMetadata.CanChangeTrackingBeEnabled 托管属性值。 若要查看无法为更改跟踪启用哪些表,请使用以下 Web API 查询:

GET [Organization URI]/api/data/v9.2/EntityDefinitions?$select=SchemaName,ChangeTrackingEnabled&$filter=ChangeTrackingEnabled eq false and CanChangeTrackingBeEnabled/Value eq false

详细信息:

使用 Web API 检索表的更改

可以使用包含标头的 Prefer: odata.track-changes Web API 请求来跟踪表中所做的更改。 此请求头要求返回一个增量链接,您稍后可以使用该链接检索表的变更。

增量链接是由服务生成的不透明链接,客户端使用它来检索结果的后续变更。 它们基于一个定义查询,该查询描述了跟踪更改的结果集。 例如,生成包含增量链接的结果的请求。 增量链接编码了正在跟踪变更的表集合,以及用于跟踪变更的起始点。 有关详细信息,请参阅 Oasis OData 版本 4.0 - Delta 链接

使用 Web API 示例检索表中的更改

此示例演示如何使用 Web API 检索对帐户表所做的更改。

请求

GET [Organization URI]/api/data/v9.0/accounts?$select=name,accountnumber,telephone1,fax HTTP/1.1
Prefer: odata.track-changes
OData-Version: 4.0
Content-Type: application/json

响应:

HTTP/1.1 200 OK
OData-Version: 4.0
Preference-Applied: odata.track-changes

{
  "@odata.context":"[Organization URI]/api/data/v9.0/$metadata#accounts(name,accountnumber,telephone1,fax)",
"@odata.deltaLink": "[Organization URI]/api/data/v9.0/accounts?$select=name,accountnumber,telephone1,fax&$deltatoken=919042%2108%2f22%2f2017%2008%3a10%3a44",
"value":[
           {
              "@odata.etag":"W/\"915244\"",
              "name":"Monte Orton",
              "accountnumber":null,
              "telephone1":"555000",
              "fax":"10101",
              "accountid":"60c4e274-0d87-e711-80e5-00155db19e6d"
           }
       ]
}

使用前面示例中返回的 @odata.deltaLink URI 提取表中的更改。 在此示例中,你创建了一个新帐户并删除了现有帐户。 上一个请求返回的增量链接用于获取这些更改,如以下示例所示。

请求

GET [Organization URI]/api/data/v9.0/accounts?$select=name,accountnumber,telephone1,fax&$deltatoken=919042%2108%2f22%2f2017%2008%3a10%3a44
OData-Version: 4.0
Content-Type: application/json

响应:

HTTP/1.1 200 OK
OData-Version: 4.0

{
          "@odata.context":"[Organization URI]/data/v9.0/$metadata#accounts(name,telephone1,fax)/$delta",
          "@odata.deltaLink":"[Organization URI]/api/data/v9.0/accounts?$select=name,telephone1,fax&$deltatoken=919058%2108%2f22%2f2017%2008%3a21%3a20",
"value":
    [
        {
            "@odata.etag":"W/\"915244\"",
            "name":"Monte Orton",
            "telephone1":"555000",
            "fax":"10101",
            "accountid":"60c4e274-0d87-e711-80e5-00155db19e6d"
        },
        {
            "@odata.context":"[Organization URI]/api/data/v9.0/$metadata#accounts/$deletedEntity",
            "id":"2e451703-c686-e711-80e5-00155db19e6d",
            "reason":"deleted"
        }
    ]
}

初始变更跟踪请求返回的增量链接响应中包含另一个增量链接。 此 delta 链接有助于检索表中所有后续的更改。 如果在初始更改跟踪请求之后未发生表更改,响应将包含空 JSON。

使用 Web API 检索表中发生的更改数量

获取更改数时,请将 $count 添加到从初始更改跟踪请求返回的增量链接中,如以下示例所示。

请求

GET [Organization URI]/api/data/v9.0/accounts/$count?$deltatoken=919042%2108%2f22%2f2017%2008%3a10%3a44
OData-Version: 4.0
Content-Type: application/json

Change Tracking Web API 请求不支持以下查询选项

在 Web API 请求中使用Prefer: odata.track-changes标头时,系统查询选项$filter$orderby$expand$top不受支持。 如果在 Web API 请求中使用这些查询选项,将收到错误消息: The \"${filter|orderby|expand|top}\" query parameter isn't supported when Change Tracking is enabled.

使用 .NET SDK 检索表的更改

为表启用更改跟踪时,请将 RetrieveEntityChanges 消息与 RetrieveEntityChangesRequest 类 一起使用,以检索该表的更改。

首次使用此消息时,它将返回表的所有记录。 可以使用该数据填充外部存储。 该消息还返回一个版本号,该版本号会随消息的下一次使用 RetrieveEntityChanges 一起发送回来,以便仅返回自该版本以来发生的更改的数据。

在检索表格更改时,需要注意以下约束:

  • 在检索更改时,您只能跟踪一个表。 如果未使用版本或令牌执行 RetrieveEntityChanges ,服务器会将其视为系统最低版本,并将所有记录都作为新记录返回。 不会返回已删除的对象。
  • 如果最后一个令牌在默认的 7 天范围内,则会返回更改。 Organization 表中 ExpireChangeTrackingInDays 列的值控制此时长,并且可以更改。 如果未处理的更改早于配置的值,系统将引发异常。
  • 如果客户端针对某张表(例如版本 1)拥有一组更改,且在下次查询更改之前有记录被创建并删除,则即使客户端最初并不拥有该项,也会获取到被删除的项目。
  • 记录按服务器端逻辑确定的顺序进行检索。 通常,调用方首先获取所有新的或更新的记录(按版本号排序),后跟已删除的记录。 如果创建或更新了 3,000 条记录并删除了 2,000 条记录,Dataverse 将返回标准表的 5,000 条记录的集合,其中前 3,000 个记录由新记录或更新的记录组成,以及已删除记录的最后 2,000 个条目。
  • 如果新建或更新的项目集合超过 5,000 个,用户可以分页浏览该集合。
  • 呼叫用户必须具有对表的组织级别读取访问权限。 如果用户具有有限的读取访问权限,系统将引发特权检查错误。

.NET SDK 示例代码

以下代码片段演示如何使用 RetrieveEntityChanges 消息检索表的更改。 有关完整示例,请参阅 使用更改跟踪将数据与外部系统同步

string token;

// Initialize page number.
int pageNumber = 1;
List<Entity> initialrecords = new List<Entity>();

// Retrieve records by using Change Tracking feature.
RetrieveEntityChangesRequest request = new RetrieveEntityChangesRequest();
request.EntityName = _customBooksEntityName.ToLower();
request.Columns = new ColumnSet("sample_bookcode", "sample_name", "sample_author");
request.PageInfo = new PagingInfo() { Count = 5000, PageNumber = 1, ReturnTotalRecordCount = false };


// Initial Synchronization. Retrieves all records as well as token value.
Console.WriteLine("Initial synchronization....retrieving all records.");
while (true)
{
    RetrieveEntityChangesResponse response = (RetrieveEntityChangesResponse)_serviceProxy.Execute(request);

    initialrecords.AddRange(response.EntityChanges.Changes.Select(x => (x as NewOrUpdatedItem).NewOrUpdatedEntity).ToArray());
    initialrecords.ForEach(x => Console.WriteLine("initial record id:{0}", x.Id));
    if (!response.EntityChanges.MoreRecords)
    {
        // Store token for later query
        token = response.EntityChanges.DataToken;
        break;

    }
    // Increment the page number to retrieve the next page.
    request.PageInfo.PageNumber++;
    // Set the paging cookie to the paging cookie returned from current results.
    request.PageInfo.PagingCookie = response.EntityChanges.PagingCookie;
}

另见

定义表的备用键
使用备用键引用记录
使用 Upsert 使用外部数据更新 Dynamics 365
使用 Web API 查询表定义