CI-D Measure dependency on Dataverse

CI-D Measure dependency on Dataverse

When measures are created in CI-D to be used in CI-J there are dependencies created which will stop you from removing the measure. CI-D is not very helpful in telling you how to remove it. I will try to be a bit more helpful.

When trying to remove the Measure this is the error I got:

Error: Detected DataVerse dependencies in Measure: ListMemberships. Please delete these dependencies and merge again.
Request ID: 14056846-b9c1-4ec8-98c2-88778e518b88
Time: 2024-12-05, 11:12:10

My investigation below with the help of Microsoft Support lead me to the understanding according to the image above. As you can see dependency is actually sort of circular, or at least one part of the dependency (dependent component) is at the entityanalytics on the record which points to msdynci_listmemberships, on the other hand (required component) on the table msdynci_listmemberships.

The fix, is to remove the record in entityanalytics. Easiest way in this case, is to just use a browser console where you are logged into the right Dynamics.

To remove the entityanalytics record that is blocking this:

Xrm.WebApi.deleteRecord('entityanalyticsconfig', 'fc105928-3170-ef11-a671-000d3a64e5b5')

After this I was able to remove the measure in CI-D.

Below I will detail the steps I did to understand this.

The first step is to look in the table “entityanalyticsconfig” searching for the name of the Measure. Its name is “msdynci_” + name of the measure. Check out the metadata if you are unsure.

<fetch top="50">
  <entity name="entityanalyticsconfig">
    <filter>
      <condition attribute="parententitylogicalname" operator="eq" value="msdynci_listmemberships" />
    </filter>
  </entity>
</fetch>
{
  "value": [
    {
      "isenabledforadls": true,
      "parententityid": "dd7613fe-806e-ef11-a670-000d3ad82e35",
      "modifiedon": "2024-09-11T11:29:54Z",
      "componentidunique": "807e7e6d-71f5-446a-8009-437cbf5a922a",
      "isenabledfortimeseries": false,
      "versionnumber": 15487568487,
      "parententitylogicalname": "msdynci_listmemberships",
      "entityanalyticsconfigid": "fc105928-3170-ef11-a671-000d3a64e5b5",
      "componentstate": 0,
      "organizationid": "ba0a9fa5-462b-45cc-b603-e9b16acd63c4",
      "solutionid": "fd140aae-4df4-11dd-bd17-0019b9312238"
    }
  ]
}

As you can see above the id is fc105928-3170-ef11-a671-000d3a64e5b5. This is the record I did the removal on above.

To further understand the dependency record for this, let’s dig into that table, searching for a record with this id.

<fetch top="50">
  <entity name="dependency">
    <attribute name="dependencyid" />
    <attribute name="dependencytype" />
    <filter>
      <condition entityname="dcn" attribute="objectid" operator="eq" value="fc105928-3170-ef11-a671-000d3a64e5b5" />
    </filter>
    <link-entity name="dependencynode" from="dependencynodeid" to="dependentcomponentnodeid" link-type="inner" alias="dcn">
      <attribute name="componenttype" />
      <attribute name="objectid" />
      <attribute name="parentid" />
    </link-entity>
    <link-entity name="dependencynode" from="dependencynodeid" to="requiredcomponentnodeid" link-type="inner" alias="rcn">
      <attribute name="componenttype" />
      <attribute name="objectid" />
      <attribute name="parentid" />
    </link-entity>
  </entity>
</fetch>
{
  "value": [
    {
      "rcn.componenttype": 1,
      "rcn.parentid": "00000000-0000-0000-0000-000000000000",
      "dcn.parentid": "00000000-0000-0000-0000-000000000000",
      "dcn.objectid": "fc105928-3170-ef11-a671-000d3a64e5b5",
      "dependencyid": "e46e52db-46a7-4585-8a6a-6ba888a5bd1f",
      "dcn.componenttype": 430,
      "rcn.objectid": "dd7613fe-806e-ef11-a670-000d3ad82e35",
      "dependencytype": 2
    }
  ]
}

The result shows us that the required component id is: dd7613fe-806e-ef11-a670-000d3ad82e35 which is of type: 1.

By checking this table in Microsoft Learn, we can see what this is: (both link and table)

By searching the table called “entity” for 430, we can find what table this represents:

https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/reference/dependency?view=dataverse-latest

ValuesLabel
1Entity
2Attribute
3Relationship
4Attribute Picklist Value
5Attribute Lookup Value
6View Attribute
7Localized Label
8Relationship Extra Condition
9Option Set
10Entity Relationship
11Entity Relationship Role
12Entity Relationship Relationships
13Managed Property
14Entity Key
16Privilege
17PrivilegeObjectTypeCode
20Role
21Role Privilege
22Display String
23Display String Map
24Form
25Organization
26Saved Query
29Workflow
31Report
32Report Entity
33Report Category
34Report Visibility
35Attachment
36Email Template
37Contract Template
38KB Article Template
39Mail Merge Template
44Duplicate Rule
45Duplicate Rule Condition
46Entity Map
47Attribute Map
48Ribbon Command
49Ribbon Context Group
50Ribbon Customization
52Ribbon Rule
53Ribbon Tab To Command Map
55Ribbon Diff
59Saved Query Visualization
60System Form
61Web Resource
62Site Map
63Connection Role
64Complex Control
70Field Security Profile
71Field Permission
90Plugin Type
91Plugin Assembly
92SDK Message Processing Step
93SDK Message Processing Step Image
95Service Endpoint
150Routing Rule
151Routing Rule Item
152SLA
153SLA Item
154Convert Rule
155Convert Rule Item
65Hierarchy Rule
161Mobile Offline Profile
162Mobile Offline Profile Item
165Similarity Rule
66Custom Control
68Custom Control Default Config
166Data Source Mapping
201SDKMessage
202SDKMessageFilter
203SdkMessagePair
204SdkMessageRequest
205SdkMessageRequestField
206SdkMessageResponse
207SdkMessageResponseField
210WebWizard
18Index
208Import Map
300Canvas App
371Connector
372Connector
380Environment Variable Definition
381Environment Variable Value
400AI Project Type
401AI Project
402AI Configuration
430Entity Analytics Configuration
431Attribute Image Configuration
432Entity Image Configuration
<fetch top="50">
  <entity name="entity">
    <attribute name="logicalname" />
    <filter>
      <condition attribute="entityid" operator="eq" value="dd7613fe-806e-ef11-a670-000d3ad82e35" />
    </filter>
  </entity>
</fetch>
{
  "value": [
    {
      "logicalname": "msdynci_listmemberships",
      "entityid": "dd7613fe-806e-ef11-a670-000d3ad82e35"
    }
  ]
}

Hence, from this I generated the image above. Since it is something of a circular reference, Microsoft Support suggested that I remove the entity analytics record with id: e46e52db-46a7-4585-8a6a-6ba888a5bd1f. However, not entirely sure what this is and hence I tried the one I had gotten in the first steps above, and that worked.

Generally I think it is a good idea to investigate what the dependencies point to, before removing something. In this case the dependency record in itself wasn’t removed, only the dependent part.

Thanks to Microsoft support for helping out with this and I hope it might shed some insights if you are having similar issues. I also think breaking down the dependency table in a tool in for instance XrmToolBox would be a great idea. I have a bit of a bad conscience for BulkDeleteManager that I own and I am not giving enough love, so feel free to build it based on this and I guess some more stuff. I will be happy to help out the the investigations if you are willing to build it.

Unable to delete table due to entityanalyticsconfig

Unable to delete table due to entityanalyticsconfig

Working on a new environment recently I had to remove a few tables. However, after removing all normal dependencies, it complained finally about a dependency to the table: entityanalyticsconfig. Never heard about it. After some googling on Microsoft Learn I found that it is about the sync to datalake, which was funny as we hadn’t set up any sync. I think it might be the new Microsoft Fabric sync from Dataverse that might be causing this. It might be switched on by default in the case that you have change tracking switched on.

Also I couldn’t find it in advanced find (the old or new one) but with https://fetchxmlbuilder.com/ in XrmToolBox I was able to find it and also the rows that were associated with it. So, I created FetchXml for these specific rows, used the tool Bulk Delete Tool (no not Bulk Delete Manager, which I made) by Andy Popkin and simply ran the delete for these specific rows. This allowed me to remove the dependency and then remove the tables.

I hope this will help you too!

Bulk Delete Manager in XTB

Bulk Delete Manager in XTB

Have you ever tried creating bulk deletes in dataverse/Dynamics 365? It is still a very old interface and it is hard to control the exact definition of what is to be deleted as you cannot see the actual FetchXML that is being used. It is also hard to see existing recurring bulk delete jobs and what FetchXML they are using. Based on these facts, my colleague Ebba Linnea Nilsson and I decided to make our first plugin for XrmToolBox (XTB). We are now proud to announce that it is released and available for free (as usual in XTB). We have also identified a bug in the platform related to this, which I will describe below.

The bulk delete functionality in dataverse and hence in Dynamics 365 CE is an essential function for many organizations. This is especially true since GDPR was introduced and there is a strong legislative requirement to remove personal data that cannot be justified to be stored.
There are also other reasons why the bulk delete functionality is more and more important and that is based on the capacity costs that can be inferred on a Power Platform tennant. Firstly just storing data, especially in the database storage in dataverse has a non trivial cost at $40/GB. There is a lot of value per GB, so it might not be justified to say that it is too expensive but removing unnecessary data is definitely something that can be worthwhile especially for larger implementations. I personally work with a customer in the travel retail industry which has millions of customers and some tables have 40M+ records. There are also a lot of integrations and automations causing a lot of data to be created. Data that at some point needs to be removed. As all data should, or there should at least be a conscious decision not to remove it and why if so.
As you might be aware, if you have read my other articles in this blog, I have previously used SSIS and Kingswaysoft to remove massive amounts of data. However, now that the API Entitlements will be introduced (6 months after the report for API Entitlements is made Generally Available), we need to start to become more and more restrictive in using the APIs for massive data management, like deletes. Hence, we try to move as much as possible to the built in Bulk Delete.

Working with the built in bulk delete functionality is a bit sad. It is very old and you have to click through a wizard kind of experience to be able to set them up. But the most limiting factor is that you cannot see the actual FetchXML of an active recurring bulk delete and you cannot input FetchXML directly into the bulk delete.

The Options page of the Bulk Delete Wizard


Having worked with this wizard you might also have noticed something a bit off. If you create a view which shows all contacts that have no activities. Then this will work when using it in the system like a view. However, if you try to use this view in a bulk delete it will “simplify” this and remove that part of the query. My thought that this was a limitation in the UI based on the fact that it is very old and hasn’t gotten any love for many years (decades). My assumption was hence that creating a bulk delete via the API would allow me to create bulk deletes that were based on FetchXMLs that you couldn’t even input from the UI.
These were the reasons for us starting to create this plugin and it was so useful that I used it in debug mode for several weeks before finalizing it and publishing it.

Now we have released the first version and you can download it directly from XTB. I would like to give a huge thanks to Jonas Rapp who helped us out a lot with both connection to his tool FetchXML Builder but also the general setup of the plugins and the details of getting it approved as a Plugin for XTB.

If you have any suggestions, comments or otherwise, leave them on the GitHub repo https://github.com/crmgustaf/BulkDeleteManager or down below. We already have a bunch of stuff we want to do.
Ah, yes, and the bug we found, it seems that the outer joins that was a rather recent addon to FetchXML is not supported by the actual platform. Hence the UI and the platform match in that perspective. Just to make it clear, what happens is that you input a FetchXML saying “All contacts with no activities” or something like that, which it will simplify to “All contacts” which is not really what you want.

As it is supported to create bulk delete jobs via the API, I do think that this still can be seen as a bug as there is no clear documentation on this or even a control when creating the bulk delete job with a FetchXML that will be incorrectly parsed. My suggestion is hence to implement the new FetchXML parser in Bulk Delete functionality, at least on the platform side. With the current setup, it is very possible that bulk deletes are created that remove a lot more than what was initially intended which can be very damaging to any organization. And from a GDPR perspective, this type of query is rather common, as it might be definied that contacts with no cases can only be stored for 2 years, but with cases for 10. To remove the ones without the cases, you would make the question “Remove all contacts with no cases with created on > 2 years”. This would then cause all contacts with created on > 2 years to be removed regardless of if it has a case or not.

To inform users of this, we have added a warning, every time a new bulk delete job is to be saved. Hopefully Microsoft will fix this soon.