Thursday, May 14, 2026

Modifying system fields value while exporting data entities in D365 F&O

System fields like CreatedDateTime, ModifiedBy, and DataAreaId are read-only by default during export. Here's how  to override them.

Every table in D365 Finance & Operations has a set of system-managed fields — CreatedDateTime, CreatedBy, ModifiedDateTime, ModifiedBy, DataAreaId, Partition, and RecId. The kernel populates these automatically on insert and update. You never touch them in normal transactional code.

But data migration is not normal transactional code.

When you're exporting data from one D365 environment and importing it into another — or feeding it to an external data warehouse — you often need those system timestamps and user IDs to travel with the record. An audit trail that shows every record as "created by Admin at 2026-05-14 09:00" because the import job ran at 9 AM is not an audit trail at all. Similarly, when importing historical data, you may need to set CreatedDateTime to the original value from the source system.

This post covers how to expose, modify, and control system field values during data entity export and import in D365 F&O — the right way.

In this article

  1. Understanding system fields and their default behavior
  2. Exposing system fields on a data entity
  3. Modifying system field values during export
  4. Security and audit considerations

Section 1

Understanding system fields and their default behavior

D365 F&O's kernel manages a fixed set of fields on every table. These fields are populated by the runtime — not by your application code — and by default they are not included in data entity mappings.

System fieldTypeSet by kernel onDefault export behavior
CreatedDateTimeUtcDateTimeInsertNot mapped to entity
CreatedByCreatedBy (userId)InsertNot mapped to entity
ModifiedDateTimeUtcDateTimeInsert + UpdateNot mapped to entity
ModifiedByModifiedBy (userId)Insert + UpdateNot mapped to entity
DataAreaIdDataAreaId (string)Insert (per company)Implicit — filtered, not exported
PartitionPartition (int64)InsertNever exposed
RecIdInt64InsertNever mapped (surrogate key)

The first four — the "audit" fields — are the ones you'll most commonly need to override. DataAreaId is a special case we'll cover in Section 5. Partition and RecId should almost never be exported or imported; they are environment-specific surrogates.

CreatedDateTime — modifiableCreatedBy — modifiableModifiedDateTime — modifiableModifiedBy — modifiableDataAreaId — conditionalPartition — read-onlyRecId — read-only

Section 2

Exposing system fields on a data entity

Before you can modify system field values during export, you need to make them visible on the data entity. By default, the Data Entity Wizard in Visual Studio does not include system fields when you generate an entity from a table. You have two options.

Option A — AOT entity designer

1

Open your data entity in the Visual Studio AOT designer.

2

Expand the data source (the primary table) and locate the system fields under the Fields node.

3

Drag CreatedDateTime, CreatedBy, ModifiedDateTime, and ModifiedBy from the data source into the entity's Fields node.

4

Set the AllowEdit and AllowEditOnCreate properties to Yes on each mapped field if you intend to write values during import.

5

Build and synchronize the entity.

Option B — Extension on an existing entity

If the entity is a standard Microsoft entity you can't overlayer, create a table extension and entity extension to add the fields:

Extension
// Step 1: Create an extension on the entity's primary data source table
// (only needed if the system fields aren't already in the entity's data source)

// Step 2: In the entity extension, add computed or mapped fields
// that reference the system fields from the data source

Which option to choose? If you own the entity (custom/ISV entity), use Option A — it's simpler and more maintainable. If you need to add system fields to a standard Microsoft entity without overlayering, use Option B with an extension and computed columns.


Section 3

Modifying system field values during export

Once the system fields are mapped to your data entity, they'll flow through during a standard DMF export — no further code changes needed for a straightforward "export as-is" scenario. But there are common cases where you need to transform the values on the way out:

/// <summary>
/// Modify DataAreaId.
/// </summary>
public void postLoad()
{
    next postLoad();
    {
        
RetailVendVendorV3Entity vendorV3Entity = this;
        new OverwriteSystemfieldsPermission().assert();
        vendorV3Entity.overwriteSystemfields(true);
        vendorV3Entity.(fieldNum(RetailVendVendorV3Entity, DataAreaId)) = 'MODE'; 
        vendorV3Entity.overwriteSystemfields(false);
        CodeAccessPermission::revertAssert();
    }
}

Section 4

Security and audit considerations

Overriding system fields is a privileged operation. The ability to set a record's CreatedBy to any user ID — or backdate CreatedDateTime — has obvious audit and compliance implications. Treat this capability with the same care as a database admin grant.

1

Create a dedicated security privilege. Don't bundle system field override capability into general data import duties. Create ContosoSystemFieldOverridePrivilege and assign it only to migration-specific roles.

2

Log every override. Enable Database Logging on the target table for the system fields. Every insert that uses overwriteSystemfields(true) should produce an audit trail entry showing the provided values versus what the kernel would have set.

3

Time-box the capability. After the migration window closes, remove the privilege. Consider wrapping the overwriteSystemfields(true) call behind a feature flag or parameter check so it's not permanently active in production code.

4

Validate against source. Run post-import reconciliation comparing the imported CreatedDateTime and CreatedBy values against the source export file. Any discrepancies indicate the kernel overwrote your values — meaning overwriteSystemfields wasn't applied correctly.






No comments:

Post a Comment