function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Yogesh BiyaniYogesh Biyani 

Validation of an approach to find orphan contacts for deletion

We would like to find all contacts without any relationships in the database and mark them for deletion.  Listing my approach below and am wondering if anyone can comment on the same.  Thank you all in advance. 

Yogesh​

Step 1 - Using the following code to identify all the relationships and the number of each
Schema.SObjectType contactSType = Contact.sObjectType;
Schema.DescribeSObjectResult dsr = contactSType.getDescribe();
string s='';
integer i=0;
for(Schema.ChildRelationship child : dsr.getChildRelationships()) {
    System.debug(i+' '+child.getChildSObject()+'--'+child.getRelationshipName()+'--'+child.getField());

        String query1='select Count_distinct('+child.getField()+ ') from '+child.getChildSObject()
 
        try 
        {   
      
            List<SObject> l=Database.Query(query1);
            integer t=(integer)l[0].get('expr0');
   
		   system.debug('r'+i+'='+ t);
 		   if(t>0)
				s+='r'+i+'='+ t+' '+child.getChildSObject()+'--'+child.getRelationshipName()+'--'+child.getField()+'; ';
       }
        
        catch(Exception e){
            
            System.debug(e.getMessage());
        }

    i++;
}

system.debug(s);

Here are the results
r0=295 AcceptedEventRelation--AcceptedEventRelations--RelationId
r1=424054 Account--Accounts_Contacts__r--Contactconnect__c
r7=112769 Attachment--Attachments--ParentId
r8=4863 CampaignMember--CampaignMembers--ContactId
r10=122885 Case--Cases--ContactId
r17=334394 ContactFeed--Feeds--ParentId
r25=107 DeclinedEventRelation--DeclinedEventRelations--RelationId
r26=1660 DuplicateRecordItem--DuplicateRecordItems--RecordId
r27=31130 EmailMessageRelation--EmailMessageRelations--RelationId
r31=2139 EntitySubscription--FeedSubscriptionsForEntity--ParentId
r32=4142 Event--Events--WhoId
r33=409 EventRelation--EventRelations--RelationId
r37=57 GoogleDoc--GoogleDocs--ParentId
r40=248704 License_With_Order__c--License_Contact__r--l_contact__c
r41=136238 License_With_Order__c--Order_B_Contact__r--o_b_contact__c
r42=245711 License_With_Order__c--Order_C_Contact__r--o_c_contact__c
r43=637 Note--Notes--ParentId
r46=13765 OpportunityContactRole--OpportunityContactRoles--ContactId
r51=8820 Quote--Quotes--ContactId
r54=892 Sertifi2_0__ContractContactJunction__c--Sertifi2_0__Signers__r--Sertifi2_0__Contact__c
r60=27768 Task--Tasks--WhoId
r61=912 TopicAssignment--TopicAssignments--EntityId
r62=239 UndecidedEventRelation--UndecidedEventRelations--RelationId
r65=740 Zendesk__Zendesk_Ticket__c--Zendesk__Zendesk_Tickets__r--Zendesk__Requester__c
r67=3828 simplesurvey__Survey__c--simplesurvey__Surveys__r--simplesurvey__Contact__c

r9=33202 CampaignMember--null--LeadOrContactId
r16=22 Contact--null--ReportsToId
r22=29 ContentVersion--null--FirstPublishLocationId
r34=6542 FeedComment--null--ParentId
r38=160901 Lead--null--ConvertedContactId
Step 2.  Create a batch process to find each record without such relationships and mark them for deletion Here is the sample code demonstrating this step using some of the relationships identified above.
List<Contact> queryResults = [select id ,(select id from AcceptedEventRelations) ,
							    (select id from PrimaryContact__r) ,
                                (select id from AccountContactRoles) ,
                                (select id from ActivityHistories),
                                (select id from Cases) from contact ORDER BY id LIMIT 10000]; 

Set<Id> resultIds = (new Map<Id,Contact>(queryResults)).keySet();
System.debug(resultIds.size());
for (Contact c : queryResults) {
 //   System.debug(c);
    if(c.Cases.size()>0||
       c.AcceptedEventRelations.size()>0||
       c.PrimaryContact__r.size()>0||
      c.AccountContactRoles.size()>0||
      c.ActivityHistories.size()>0)
    {
  /*      for (Case c1 : c.Cases) {
            System.debug(c1);
        }*/
       // System.debug('Keep');
        resultIds.remove(c.id);
    }
    else 
    {
        //System.debug('Delete1');
     
    }
        
        for (ActivityHistory c1 : c.ActivityHistories) {
         //   System.debug(c1);
        }
    
    for (Account c1 : c.PrimaryContact__r) {
       // System.debug(c1);
    }
}

System.debug(resultIds.size());

List<Lead> ls =[Select Id,ConvertedContactId from Lead where ConvertedContactId IN :resultIds];

if(ls.size()>0)
{
    for(Lead l : ls)
    {
        resultIds.remove(l.ConvertedContactId);
        system.debug('removed id '+l.ConvertedContactId);
    }
}

System.debug(resultIds.size()); // these the contacts to mark for deletion