Newer Version Available
Working with Polymorphic Relationships in SOQL Queries
A polymorphic relationship is a relationship between objects where a referenced object
can be one of several different types. For example, the What relationship
field of an Event could be an Account, a Campaign, or an Opportunity.
The following describes how to use SOQL queries with polymorphic relationships in Apex. If you want more general information on polymorphic relationships, see Understanding Polymorphic Keys and Relationships in the Force.com SOQL and SOSL Reference.
You can use SOQL queries that reference polymorphic fields in Apex to get results that depend on the object type referenced by
the polymorphic field. One approach is to filter your results using
the Type qualifier. This example queries Events
that are related to an Account or Opportunity via the What field.
Another approach would be to use the TYPEOF clause in the SOQL SELECT statement. This example
also queries Events that are related to an Account or Opportunity
via the What field.
These queries will return a list of sObjects where the relationship
field references the desired object types.
1List<Event> = [SELECT Description FROM Event WHERE What.Type IN ('Account', 'Opportunity')];1List<Event> = [SELECT TYPEOF What WHEN Account THEN Phone WHEN Opportunity THEN Amount END FROM Event];If you need to access the referenced object in a polymorphic relationship,
you can use the instanceof keyword
to determine the object type. The following example uses instanceof to determine whether an
Account or Opportunity is related to an Event.
Note that you must assign the referenced sObject that
the query returns to a variable of the appropriate type before you
can pass it to another method. The following example queries for User
or Group owners of Merchandise__c custom objects using a SOQL query with a TYPEOF clause, uses instanceof to determine the owner
type, and then assigns the owner objects to User or Group type variables
before passing them to utility methods.
1Event myEvent = eventFromQuery;
2if (myEvent.What instanceof Account) {
3 // myEvent.What references an Account, so process accordingly
4} else if (myEvent.What instanceof Opportunity) {
5 // myEvent.What references an Opportunity, so process accordingly
6}1public class PolymorphismExampleClass {
2
3 // Utility method for a User
4 public static void processUser(User theUser) {
5 System.debug('Processed User');
6 }
7
8 // Utility method for a Group
9 public static void processGroup(Group theGroup) {
10 System.debug('Processed Group');
11 }
12
13 public static void processOwnersOfMerchandise() {
14 // Select records based on the Owner polymorphic relationship field
15 List<Merchandise__c> merchandiseList = [SELECT TYPEOF Owner WHEN User THEN LastName WHEN Group THEN Email END FROM Merchandise__c];
16 // We now have a list of Merchandise__c records owned by either a User or Group
17 for (Merchandise__c merch: merchandiseList) {
18 // We can use instanceof to check the polymorphic relationship type
19 // Note that we have to assign the polymorphic reference to the appropriate
20 // sObject type before passing to a method
21 if (merch.Owner instanceof User) {
22 User userOwner = merch.Owner;
23 processUser(userOwner);
24 } else if (merch.Owner instanceof Group) {
25 Group groupOwner = merch.Owner;
26 processGroup(groupOwner);
27 }
28 }
29 }
30}