how can i read the ReferenceTo field on the FieldDefinition object

When I ran the command sfdx force:data:soql:query --query="SELECT QualifiedApiName, (SELECT ReferenceTo,QualifiedApiName FROM Fields WHERE RelationshipName!=null LIMIT 1) FROM EntityDefinition WHERE QualifiedApiName = 'Account' LIMIT 1" --targetusername sandbox --usetoolingapi --json, it gave the below output:

{
  "status": 0,
  "result": {
    "size": 1,
    "totalSize": 1,
    "done": true,
    "queryLocator": null,
    "entityTypeName": "EntityDefinition",
    "records": [
      {
        "attributes": {
          "type": "EntityDefinition",
          "url": "/services/data/v48.0/tooling/sobjects/EntityDefinition/Account"
        },
        "QualifiedApiName": "Account",
        "Fields": {
          "size": 1,
          "totalSize": 1,
          "done": true,
          "queryLocator": null,
          "entityTypeName": "FieldDefinition",
          "records": [
            {
              "attributes": {
                "type": "FieldDefinition"
              },
              "ReferenceTo": {
                "referenceTo": [
                  "Account"
                ]
              },
              "QualifiedApiName": "MasterRecordId"
            }
          ]
        }
      }
    ]
  }
}

We can see that ReferenceTo contains property named referenceTo and it is a string array.

When I run this System.debug(Schema.SObjectType.FieldDefinition.fields.ReferenceTo.getType());, it gives the output COMPLEXVALUE and this is not listed here

Based on above findings, I came up with the below workaround where we can serialize and deserialize FieldDefinition object.

List<EntityDefinition> allObjects = [SELECT QualifiedApiName, (SELECT ReferenceTo,Label,QualifiedApiName FROM Fields WHERE RelationshipName!=null) FROM EntityDefinition WHERE QualifiedApiName = 'Account'];

for (EntityDefinition thisObj : allObjects) {
    for (FieldDefinition thisField : thisObj.fields) {

        String fieldDefinitionJSONStr = JSON.serialize(thisField);
        Map<String,Object> fieldDefinitionJSONMap = (Map<String, Object>)JSON.deserializeUntyped(fieldDefinitionJSONStr);
        Map<String,Object> referenceToJSONMap = (Map<String,Object>)fieldDefinitionJsonMap.get('ReferenceTo');
        List<Object> referenceToList = (List<Object>)referenceToJSONMap.get('referenceTo');

        if(referenceToList != NULL){
            for(Object obj: referenceToList){
                System.debug(thisField.QualifiedApiName + 'points to object: ' + (String)obj);
            }
        }
    }
}

Tags:

Soql