Post by Cruz Margaix |
You’ve got it. Microsoft finally resolved your extensibility request and that enum, which was preventing you from removing all your overlays, is now extensible. You’re bursting with enthusiasm. Plus extending an enum is so easy. Your Dynamics 365 Finance and Operations (D365FO) solution will be in the extensions only world in a minute. I can imagine a broad smile on your face.
I apologise for breaking that magical moment. But I must bring you back to reality and say that if you have a database which is already using the overlayered enum values, there are some precautions you will have to take to ensure you don’t end up with corrupted data after the data upgrade. The process may take a few minutes, but I promise it won’t be long.
In D365FO enums that are not extensible keep the numeric value of each element in the metadata. You can find the xml file with your overlayered enum metadata in your PackagesLocalDirectory folder. As an example, if the enum you’re overlayering belongs to the ApplicationSuite model your xml file can be found in the following route:
<PackagesLocalDirectory>\ApplicationSuite\<Your model name>\AxEnum\Delta
As you can see, there’s a numeric value assigned to the element you added.
However, extensible enums do not use the metadata to store their numeric values. Instead these values are stored in the database and assigned dynamically by the database synchronisation process.
The ENUMIDTABLE table stores the base enum ids while the ENUMVALUETABLE table stores the numeric values assigned to every element of the base enum. While the ENUMIDTABLE table contains records for every base enum in the system, ENUMVALUETABLE is only populated for extensible enums.
In our example, ProjSortValue enum has been made extensible in version 8.1 (https://docs.microsoft.com/en-us/dynamics365/unified-operations/dev-itpro/extensibility/extensibility-changes-81) therefore we can find its related records in the ENUMIDTABLE and ENUMVALUETABLE tables:
When we remove the customisation on an overlayered enum and create an extension to add our new element, the reference to the numeric value that element had assigned in the old metadata is lost. Therefore, when the database is synched with the new code, the synchronisation process will assign an arbitrary numeric value to the extended element which won’t probably match the numeric values already stored in the database when the enum was overlayered. As a result, the upgraded data won’t reference the new enum value.
In order to prevent data loss, the synchronisation process needs to have a reference of the numeric value to be used. And this reference can still be provided by the metadata.
First, you’ll have to create an extension for the enum and add your new values following the steps detailed in this page:
Once the extended enum is created and the new element added, you can still set up a numeric value by editing the xml file. Locate the xml file for your enum in the PackagesLocalDirectory folder:
<PackagesLocalDirectory>\<Your model name>\AxEnumExtension
And add the numeric value it had previously assigned:
The database synchronisation process will take this value from the metadata to populate ENUMVALUETABLE. As a result, the references to your enum element will be still valid in the database.
Please ensure a data upgrade test is run and a thorough verification of the content of the impacted tables is performed.
If the overlayered enum was extensible in the source version you’re upgrading from, it won’t be necessary to change the metadata file since your custom values will already exist in the ENUMVALUETABLE table.
This approach is only recommended to keep data consistency after a data upgrade. I would strongly discourage you to use it for any other purposes. Keeping in place old practices such as forcing specific numeric values for enums prevents us from moving forward and adopting new ways of working, but above all it’s a risk not worth taking.