Some times we need to populate fields on Data Entity based on some calculated X++ logic instead of binding them directly from table. It is possible to satisfy this requirement by using virtual fields in data entities.
Virtual fields can you used in the import scenarios, to bring additional data that is not available on data sources but needed for an entity, but it’s slower from an export perspective and you can’t skip staging data for export scenarios in this case.
Virtual field features
- Is a non-persisted field.
- Is controlled by custom X++ code.
- Read and write happens through custom X++ code.
- Virtual fields are typically used for intake values that are calculated by using X++ code and can’t be replaced by computed columns.
- Search and filtering on virtual fields are not supported.
How to create virtual field
- In the designer for the entity, right-click the Fields node, and then click New > String Unmapped Field.
- In the properties pane for the unmapped field, set the Name property.
- Set the Is Computed Field property to No. Notice that you leave the DataEntityView Method empt
Export – set virtual field
When exporting the data, to enhance the virtual fields it is necessary to override the postLoad method. RecId can be used to retrieve the primary datasource record. For example:
public void postLoad()
{
DirPersonUser personUser;
super();
PurchReqAuthorizationLegalEntity purchReqAuthorizationLegalEntity = this.findPurchReqAuthorizationLegalEntityByRecId(this.RecId);
if (purchReqAuthorizationLegalEntity.RecId)
{
this.Company = CompanyInfo::findRecId(purchReqAuthorizationLegalEntity.BuyingLegalEntity).DataArea;
}
}
Import – set virtual field
When it is necessary to value virtual field in case of import, it is necessary to override the mapEntityToDataSource method. When update is called, mapEntityToDataSource methods are invoked for each data source.
public void mapEntityToDataSource(DataEntityRuntimeContext _entityCtx, DataEntityDataSourceRuntimeContext _dataSourceCtx)
{
CompanyInfo company;
super(_entityCtx, _dataSourceCtx);
if (_entityCtx.getDatabaseOperation() == DataEntityDatabaseOperation::Insert || _entityCtx.getDatabaseOperation() == DataEntityDatabaseOperation::Update)
{
if (_dataSourceCtx.name() == "PurchReqAuthorizationLegalEntity")
{
PurchReqAuthorizationLegalEntity myTable = _dataSourceCtx.getBuffer();
company = CompanyInfo::findDataArea(this.Company);
myTable.ValidFrom = today();
myTable.ValidTo = dateMax();
myTable.BuyingLegalEntity = company.RecId;
}
}
}