There is a conceptual issue here
When you use setWhatId(..)
you are setting the center of attention object to use in the email template. If a Visualforce email template, then this object is bound to the template's relatedTo=
attribute.
The target object then is used by Salesforce to instantiate a standard controller for that object and because of your markup, implicitly binds parent and children objects as well.
So, If the whatId
object is Invoice, and Invoice has lookups to Contact (like a bill to contact), your email template would use references like this:
relatedTo.BilltoContact__r.FirstName
When you use setTargetObjectId(..)
you are identifying the recipient of the email. This is bound to the recipientType
attribute in the VF template.
So, your use case might then be
emailObj.setTargetObjectId(someContactId); // bound to recipientType
emailObj.setWhatId(someInvoiceId); // bound to relatedTo