If you try accessing the same data using the various mechanisms listed below will you always receive back identical values?
- Dynamics/Power Apps UI
- Dataverse Organizational Service
- Dataverse Web API
- TDS Endpoint
- Power BI/Power Query Dataverse Connector
- Azure Synapse Link for Dataverse (formerly “Export to data lake”)
The data access options listed on the right take a shortcut when reading data: They do not use the normal Retrieve and RetrieveMultiple messages to fetch data. If you are using a plugin that relies on these messages to impact data reads (e.g. to override, block or replace data), those effects will be skipped.
For example, say you’re using a plugin that computes a column’s value on the fly each time it is read. A data read from the relevant table using any of the options on the left will include this computation. A data fetch using one of the options on the right will not; instead, the computation will be skipped.
This difference in behavior is something to be aware when using the options listed on the right. If you are using plugins that rely on receiving Retrieve or RetrieveMultiple messages, reengineering is necessary in order for the desired behaviors to still be achieved when data is accessed using the mechanisms on the right. You may be able to buy some time by temporarily avoiding the list on the right; however, this may not be a viable long-term solution, as it is likely that the TDS endpoint and Power BI connector will prove popular and so hard to avoid indefinitely.
When working in the Dynamics/PowerApps user interface (or when using another method to access data stored in Dataverse), it’s easy to presume we’re directly working on top of a database. When we load data, it may seem like it is being read directly out of table rows into the user interface, or when we save data, that the changes are written directly back into the data store.
But this isn’t normally the case. A key component of Dataverse is an intermediate message-processing layer that sits between the user interfaces/external interfaces and the underlying physical data store. For example, when you create or update a record, your action triggers the sending of a “create” or “update” message (respectively) which contains the details of the addition or change you want made. Another piece of infrastructure listens for these messages, and when it receives one, uses the message’s data to update the database appropriately.
A beauty of this design is that intermediate actors can be injected into the message-passing flow. A plugin can add a step which listens for certain messages, overriding, modifying or augmenting what they otherwise normally would do. For example, say anytime an account’s status is updated to inactive, you want the statuses of all associated contacts to also be set to inactive. You could do this with a plugin which, when it “hears” an appropriate update message for an account, augments that message’s normal behavior by triggering the contact updates.
Normally, this intermediate message-passing layer is also used for data reads. A plugin can listen for and respond to the relevant data fetch messages (Retrieve and RetrieveMultiple). This capability opens up the possibility for a plugin to use its own logic to do things like calculate column values on the fly, implement complex security rules controlling access to underlying data or even to dynamically compute the complete table that is returned.
The mechanisms listed on the right do not use messages to fetch data. Any plugins you use which listen for these messages won’t run when data is fetched using the list of data access mechanisms on the right.