I couldn’t find any example code on the Net to accomplish a task that is probably common amongst many Salesforce implementations. I have a requirement to link a second account to an opportunity in Salesforce. In my use case, the primary opportunity account represents a construction project general contractor, and the second linked account represents the building owner. I need to automatically pull the building owner account contacts into the opportunity contact roles list. Here’s the Salesforce Trigger to do just that:

trigger AssignBuildingOwnerAccountContact on Opportunity (after insert, after update) {

    System.debug(Logginglevel.DEBUG, 'Starting AssignBuildingOwnerAccountContact trigger');

    // holds all contacts
    List<OpportunityContactRole> lstOpportunityContacts = new List<OpportunityContactRole>();    
    List<AccountContactRole> lstAccountContacts = new List<AccountContactRole>();
    // holds building owner account
    List<Account> lstBuildingOwner = new List<Account>();
    // get each building owner
    for(Opportunity objOpportunity : Trigger.new) {
        System.debug(Logginglevel.DEBUG, 'Start Trigger loop on Opportunity' + objOpportunity.Name);
        // get building owner (of object type account)
        if(objOpportunity.Building_Owner__c == NULL) {
        	System.debug(Logginglevel.DEBUG, 'No building owner');
        System.debug(Logginglevel.DEBUG, 'Got building owner ID from opportunity');
        lstBuildingOwner = [SELECT Id FROM Account WHERE Id = : objOpportunity.Building_Owner__c];
        if(lstBuildingOwner.size() < 1) {
        	System.debug(Logginglevel.DEBUG, 'No building match for id');
        System.debug(Logginglevel.DEBUG, 'Found building owner in database');
        // get all contacts associated with building owner
        lstAccountContacts = [SELECT ContactId FROM AccountContactRole WHERE AccountId = :lstBuildingOwner[0].Id];
        if(lstAccountContacts.size() < 1) {
        	System.debug(Logginglevel.DEBUG, 'No building contacts to insert into opportunity roles');
        System.debug(Logginglevel.DEBUG, 'Found building owner contacts in database');
        // add/update building owner contacts to opportunity contact roles
        for(AccountContactRole newOppRoleContact : lstAccountContacts) {
          System.debug(Logginglevel.DEBUG, 'Add building owner contact to opportunity');
          lstOpportunityContacts.add(new OpportunityContactRole(ContactId=newOppRoleContact.ContactId, OpportunityId=objOpportunity.Id, Role='Building Owner'));
        upsert lstOpportunityContacts;
        System.debug(Logginglevel.DEBUG, 'Save/update new building owner contacts to opportunity in database');