D365FO X++ tip for developers: How to deal with container fields on data entities by converting them to files

Intro

In some cases, we need to create a data entity for a table that has one or more fields that are of type container.

Image containers

If these containers are used to hold the value of a bitmap image (in the case where these fields use an EDT that extends the base Bitmap EDT), then we need to do the following for the image to be exported as a file in the data entity package:

  1. On the staging table of the data entity, create a field that is of the same type and uses the same EDT as the field on the original table (the table that is the data source of the data entity):
    Data source table properties (just for comparison):

    Staging table properties:
  2. Next on the staging table, we need to add a new field of type string that has the same name of the field created in step 1, but with FileName appended to the name:

For a bitmap image, these 2 steps should be enough and the data management framework will automatically link these two fields and successfully export the image as a file in the data entity package in the Resources subdirectory:

Non-image containers

In the case where we have a container field that does not contain image data, the framework won’t know how to handle it automatically, so we’ll need to help it along.

If we do the same setup as we did above for a bitmap image, we’ll get the following error:

Error exporting the bitmap data.
Wrong argument type for function. - (S)\Classes\BinData\setData

To make non-image containers work, we need to do the following:

  1. On the staging table of the data entity, create a field that is of type string and use the EDT Notes (it will probably also work with any other string EDT that has a (Memo) string size):
    Data source table properties (just for comparison):

    Staging table properties:
  2. Next on the staging table, we need to add a new field of type string that has the same name of the field created in step 1, but with FileName appended to the name:
  3. Now, for non-image containers, we need to override the getFieldsToBeConvertedToFile() method:
public static container getFieldsToBeConvertedToFile()
{
    return [[fieldstr(DocCustAutomationSysEmailSystemTableEntity, InvoiceAttachmentSourceSelected), // This is the field name of the container field that is found on the data entity.
            fieldstr(DocCustAutomationSysEmailSystemTableStaging, InvoiceAttachmentSourceSelected), // This is the field name of the string field that is found on the staging table.
            fieldstr(DocCustAutomationSysEmailSystemTableStaging, InvoiceAttachmentSourceSelectedFileName), // This is the field name of the file name string field that is found on the staging table.
            true]]; // This is the parameter that determines whether the passed parameter is an image or not. The name of the parameter, confusingly, is isNotImageData and it's false by default, meaning that by default it expects an image.
}

Closing thoughts

This should be all that is needed to create entities with container fields that will be exported as files in the data entity package.

Additional reading:
Docentric blog article: Import/Export Container Data Fields Using D365FO Data Management
Microsoft documentation: Build and consume data entities