[SalesForce] Retrieving Dynamic SOQL results. Runtime error – “Invalid field Owner.Name for…”

I had a question in regards to dynamically retrieving the results of Dynamic SOQL that I have set up in my controller. I want to be able to access fields on the Lead object (Lead.Name) itself as well as relationships (Lead.Owner.Name).

The dynamic soql works great, but I'm having problems when I try to read in the values of the result. Is there any way I can pull in values for fields on the sObject itself as well as values from a relationship? Here's a snippet of the problematic code:

Lead lead = [SELECT Id, OwnerID, Owner.Name, Name from Lead where Id = '00QP0000003r4f8']; //*Note in the actual code I'm using a String and Database.query()
String apiname = 'owner.name';
String apiname2 = 'Name';

//this works, but we don't want to hardcode the value
system.debug('lead owner.name ='+lead.owner.name);

String result1 = String.ValueOf(lead.get(apiname2));
System.Debug(result1);
//returns name of the lead record just fine

String result2 = String.ValueOf(lead.get(apiname));
//ERROR on runtime - System.SObjectException: Invalid field owner.name for Lead

System.Debug(result2);

Best Answer

In addition to Doug B's answer, I wrote a utility method to do this:

public static Object getSobjectField(Sobject sObj, String fieldRef) {

        Sobject sObjNode    = sObj;
        //  fieldRef is relative to the sobject and may include relationshipNames
        //      Handle use cases:
        //          fld0                - fld0 on Sobject passed as argument
        //          fld0.fld1           - fld1 is on sobject fld0
        //          fld0.fld1. ... fldN - fldN is on sobject fldN-1
        String[] fieldList  = fieldRef.split('\\.');

        for (Integer i=0; i < fieldList.size() -1; i++) {
            sObjNode    = (Sobject) sObjNode.getSobject(fieldList[i]);  // intermediate fields are sobjects
            if (sObjNode == null) return null;
        }
        return sObjNode.get(fieldList[fieldList.size()-1]); // use fldN
    }

Example: String ownerName = (String) Util.getSobjectField(lead,'owner.name');