This is my query
SOBject acc = [Select Id, Name, (Select Id, Account.Parent.Parent.Name, Name from Contacts__r) from Sales_Location__c where Id ='a005j000009xxxBAxU'];
Contact abc =(Contact)(acc.getSobjects('Contacts__r')).get(0);
System.debug(abc.get('Account.Parent.Parent.Name'));
But instead of using get() if I directly use abc.Account.Parent.Parent.Name, I am getting result. But I don't know why my code fails in case of get(). In Actual scenario abc is of SObject type that's why I need to use get() here.
sObject.get()
works on only 1 field, it will not travel via "dots". See https://salesforce.stackexchange.com/a/24804/799 (shameless plug, it's my own answer)
You can try like that
Sales_Location__c location = [Select Id, Name,
(Select Id, Account.Parent.Parent.Name, Name from Contacts__r)
from Sales_Location__c
where Id ='a005j000009xxxBAxU'];
if(!location.Contacts__r.isEmpty()){
Contact abc = location.Contacts__r[0];
if(abc.Account != null && abc.Account.Parent != null && abc.Account.Parent.Parent != null){
System.debug(abc.Account.Parent.Parent.Name);
} else {
System.debug('there is no grandparent account');
}
}
but this null checking gets very annoying after a while. There's a fairly recent addition https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SafeNavigationOperator.htm
// the query is stupid, the parent name will always be null
// but my point is it's accessed safely, it won't throw the
// null reference exception
Contact c = [SELECT Account.Parent.Name
FROM Contact
WHERE Account.ParentId = null
LIMIT 1];
System.debug(c.Account?.Parent?.Name);
P.S. even if your function receives a generic sObject - you can always try to cast it back to the original
Sales_Location__c loc = (Sales_Location__c) abc;
So it'll give you simpler code later on, compile-time checks... Don't suffer with generic sobjects if you don't have to. Check instanceof
too if your function can accept sobjects from multiple sources