0

I want to create an Apex function that takes a recordId of unknown entity type, identifies the entity type and subsequently returns all child records (name, id) of the given record. In addition, the function should also return all the parents of the given record (name, id).

Eg:

for recordId x (of entity type Account which is unknown)

It should return something like:

Type: Account

Children

Contacts (type: look up/master detail)

Contact 1 Contact 2 Contact 3 ...

Opportunities (type: look up/master detail)

Opp 1 Opp 2 Opp 3 ...

Parents

Similar to above along with type (look up or master detail)

I'm clueless as to how to go about this. Any help is much appreciated.

0

1 Answer 1

1

Getting the object name from an Id is easy.
Getting the parent and child records is harder (and may be impossible).

The Id class provides the getSObjectType() method, which gives you an SObjectType instance. From there, you can get the describe information, and then get the object name.

Schema.DescribeSObjectResult sobjDescribe = myId.getSObjectType().getDescribe();

System.debug('object name = ' + sobjDescribe.getName());

The DescribeSObjectResult class has other methods/properties that can then help you get the parent and child relationships.

For child records, .getChildRelationships() should be what you're looking for. You'd iterate over those results and be interested in calling .getRelationshipName(). Be aware that you can only include 20 child subqueries in a single query (documentation).

For the parent records, you'd need to go through each individual field and check to see if it's a relationship field. You'd then extract the relationship name (the label will be something like AccountId or My_Lookup__c, the relationship name would be Account and My_Lookup__r respectively). It's the relationship name that you'd be using in your query.

for(Schema.SObjectField sof :Schema.SObjectType.Opportunity.fields.getMap().values()){
    DescribeFieldResult dfr = sof.getDescribe();

    if(dfr.getType() == Schema.DisplayType.REFERENCE){
        system.debug(dfr.getRelationshipName());
    }
}

There are some occasions where you'd need to put some more work in, such as when a single relationship field can point to one of multiple parent record types, but the above should get the job done in most situations.

A single query can have up to 55 child-to-parent relationships (same documentation).

Building the query for this is not going to be fun, but some tips:

  • Store the parent relationships and child relationships in two different lists
  • Make your life easier by using string replacement
    • for parent relationships, something like String.replace('(.*)', '{0}.Id, {0}.Name'); should help you take "Account" and turn that into "Account.Id, Account.Name"), but be aware that not every object has a name field (e.g. Case, which has Subject instead)
    • for child relationships, take a similar tack. String.replace('(.*)', '(SELECT Id, Name FROM {0})');
  • Use String.format() and String.join() to build the final query
    • e.g.
        String.format('SELECT {0}, {1} FROM {2} WHERE Id = {3}', new List<String>{
            String.join(parentFields, ', '),
            String.join(childQueries, ', '),
            myId.getSObjectType().getDescribe().getName(),
            myId
      });
      

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .