Showing posts with label data entity. Show all posts
Showing posts with label data entity. Show all posts

Friday, January 22, 2021

D365FO data entities with financial dimension requires special field names

 While creating data entities using financial dimensions, do not forget that those are backed in background by special classes via SysDataEntityPersister class




Those latter help resolving selected values (similar to what we see in segmented entry in forms). 



Each class is meant to serve a particular EDT, for example


/// <summary>
/// The <c>LedgerAccountDimensionDataEntityResolver</c> class resolves data entity ledger account values.
/// </summary>
[
System.ComponentModel.Composition.ExportMetadataAttribute("DimensionSFKType", identifierstr(LedgerDimensionAccount)),
System.ComponentModel.Composition.ExportAttribute("Microsoft.Dynamics.AX.DimensionDataEntitySFKFieldResolver")
]
public class LedgerAccountDimensionDataEntityResolver extends DimensionDataEntitySFKFieldResolver
{
    Name accountStructure;
...


In order to let it work correctly, some fields in your data entity must have particular names.


public class DimensionDataEntityConstants
{
    public static const str HasDimensionDataSourcesCustomPropertyName = '__HasDimensionDataSources__';
    public static const str ProviderCacheName = 'DimensionDataEntitySFKProviderCacheName';
    public static const str AccountStructureSuffix = 'AccountStructure';
    public static const str DisplayValueSuffix = 'DisplayValue';
    public static const str DisplayValueTypeName = 'DimensionDisplayValue';
}




Thursday, May 30, 2019

Overcome 'The natural key for the table TableName was not found' while creating data entity

When we need to create a data entity for a table without a natural key, say VendTrans, Data entity Wizard shows the following error.



In order to overcome this limitation, we can simply feed the wizard with a copy of a query table with a natural key added. Lately we can just replace one field and its related relation and index in the data entity and staging table.

So, find VendTrans table and create a copy into your model. Delete all methods, add new String field f, make a new unique index based on this field and make this index primary and clustered. You do not need either build or synchronize your solution yet.


Now run the Wizard again with VendTransCopy as a source, and you will get all needed objects created.

Go to data entity view and change its query data source to VendTrans table.






Then rename field f to something meaningful as VendTrans_RecId and point it to VendTrans.RecId.


Add a new Int64 field with the same name in the related staging table





Then use it instead of field f in the index and relation.





You can delete field f as well as VendTransCopy table.

That is it! Now build and synchronize the solution. The new data entity is ready for use.








Wednesday, March 6, 2019

Computed column for union values from multiple outer joined data sources in view

Let's say you have a multiple outer joined data sources with similar fields, which can be merged by union to one target field.

PSAActualEntity  data entity (in D365) can be a good example, if you add ProjCostTrans, ProjItemTrans, and ProjEmplTrans to its root data source table ProjTransPosting, which has appropriate relations to each of them.



All aforementioned have CategoryId field, which can be present in one table only at a time.


 Let's place a new computed string field with the following static method with a nested if.


private static server str transCategoryId()
    {
        str         sRet;
        tableName   viewName                = identifierStr(avrPSAActualEntity);
        str         cCategoryProjCostTrans  = SysComputedColumn::comparisonField(viewName,
                                                                                    identifierStr(ProjCostTrans),
                                                                                    fieldStr(ProjCostTrans, CategoryId));
        str         cCategoryProjItemTrans  = SysComputedColumn::comparisonField(viewName,
                                                                                    identifierStr(ProjItemTrans),
                                                                                    fieldStr(ProjItemTrans, CategoryId));
        str         cCategoryProjEmplTrans  = SysComputedColumn::comparisonField(viewName,
                                                                                    identifierStr(ProjEmplTrans),
                                                                                    fieldStr(ProjEmplTrans, CategoryId));
        str         sCategoryProjCostTrans  = SysComputedColumn::returnField(viewName,
                                                                                    identifierStr(ProjCostTrans),
                                                                                    fieldStr(ProjCostTrans, CategoryId));
        str         sCategoryProjItemTrans  = SysComputedColumn::returnField(viewName,
                                                                                    identifierStr(ProjItemTrans),
                                                                                    fieldStr(ProjItemTrans, CategoryId));
        str         sCategoryProjEmplTrans  = SysComputedColumn::returnField(viewName,
                                                                                    identifierStr(ProjEmplTrans),
                                                                                    fieldStr(ProjEmplTrans, CategoryId));
        sRet =
            SysComputedColumn::if(SysComputedColumn::isNotNullExpression(cCategoryProjCostTrans),
                                    cCategoryProjCostTrans, 
                                    SysComputedColumn::if(SysComputedColumn::isNotNullExpression(cCategoryProjItemTrans),
                                                            sCategoryProjItemTrans,
                                                            SysComputedColumn::if(SysComputedColumn::isNotNullExpression(cCategoryProjEmplTrans),
                                                                                sCategoryProjEmplTrans,
                                                                                SysComputedColumn::returnLiteral('')
                                                                                )
                                                        )
                                );

        return sRet;
    }