A synchronization job uses Web API delta links to keep an external table in step with Dataverse accounts. New and updated accounts arrive correctly, but accounts deleted in Dataverse never disappear from the external table. The job's code skips any entry in the response that has no account columns. What is the cause?
Select an answer to reveal the explanation.
Short Explanation
Deleted rows don't come back looking like accounts; they come back as little tombstones with an ID and a reason of 'deleted'. Your code tossed the tombstones because they had no columns. Read them and delete the matching rows on your side.
Full Explanation
When a delta link returns changes, created and updated rows appear with their selected columns, while deleted rows appear as separate entries whose context ends in $deletedEntity and which carry only the row's id and a reason of deleted. Code that ignores entries without column values discards exactly those deletion records, so the external table never removes them. The fix is to detect deleted-entity entries and delete the matching external rows by ID. Change tracking does report deletions, which is a key advantage over filtering on modifiedon, so a full comparison is unnecessary. An expired token does not silently drop deletions; requesting changes with a token older than the retention period produces an error that forces a full resynchronization. A $filter is not supported with change tracking requests, and deleted entries are returned without any filter. Exam caveat: in the SDK, RetrieveEntityChanges returns the same split as NewOrUpdatedItem and RemovedOrDeletedItem objects, and the same mistake of handling only the first type produces the same symptom. Operational check: delete a test account, call the stored delta link, confirm the response contains a deleted-entity entry with that account's ID, and confirm the job removes the external row.