1

I what to write a soql to query the user email address but failed to do so.

Basically from a task, I want to find its related lead(WhoID) then find the lead owner, then find the owner's email.

my query look like this

List<Task> myTasks = [SELECT Id,
                            WhoId,
                            Who.Owner.Email
                     FROM   Task
                     WHERE  Id = :myLeadIds];

Salesforce does not recognize the 'Owner relationship' and I dont understand why.

I tried:

List<Task> myTasks = [SELECT Id,
                             WhoId,
                             Who.Email
                      FROM   Task
                      WHERE  Id = :myLeadIds];

Which is not the email I wanted but salesforce does not prompt error so I assume it proved that it can recoginze the 'who' relationship, so I dont understand why the 'Owner' lookup field is not recognized while the Email field is. Thanks in advance.

1 Answer 1

5

WhoId and WhatId on the Task SObject are polymorphic relationship fields.

They can hold an Id (just one Id) from a variety of different SObjects, so the standard way of querying/accessing parent data doesn't work.

You could simply gather the whoId from your tasks and use that to feed a second query (e.g. [SELECT Owner.Email FROM Lead WHERE Id IN :taskWhoIdList]), and put the result into a map. You could then iterate over your Task records, and myLeadMap.get(task.WhoId);

The other option is a feature Salesforce gave us a few releases ago (ok, a bit further back than I realized. This looks like it was released back in Winter '13), allowing us to work with ploymorphic relationships in a single query. (The documentation from the SOQL/SOSL guide is probably a better reference here).

Using that, your query would look something like [SELECT TYPEOF Who WHEN Lead THEN Owner.Email END FROM Task WHERE Id IN :taskIdList]

You'll still get a List<Task> from the query, and you'd use instanceOf to ensure you only try to access Lead data when WhoId points to a Lead.

for(Task t :taskQuery){
    if(t.Who instanceOf Lead){
        system.debug(t.Who.Owner.Email);
    }
}
1
  • 1
    you could add in Type along with TYPEOF in the same query to eliminate the need for filtering afterwards - WHERE Who.Type IN ('Lead') Jul 16, 2021 at 16:56

You must log in to answer this question.

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