[SalesForce] Trigger to update field values from another object

I got this scenario where there's two object say A and B, both of them having a field called BCode and Code . Now, if the values match then another field called X in A has to be populated with the value of X which is in object B. I've written a trigger for this on Object B but while trying to dataload few records of B i'm getting this error

Execution Of AfterUpdate Caused By: System.ListException: Duplicate Id In List.

Can someone please help as to what wrong I'm doing here?
There's no relationship between the two objects.

trigger UpdateXField on B__c (after insert,after update){

Set<String> bCode = new set<String>();
List<A__c> updatedAList = new List<A__c>();

for(B__c b:Trigger.New){
    bCode.add(b.Code__c);
}

List<A__c> AList = [SELECT BCode__c,X__c FROM A__c 
                                WHERE RecordType.Name = 'Test' AND BCode__c IN:bCode LIMIT : Limits.getLimitQueryRows() - Limits.getQueryRows()];
if(!AList.isEmpty()){                                
   for(B__c b:Trigger.New){
        for(A__c a:aList){
            if(b.Code__c == a.BCode__c && b.Status__c=='Approved' && b.Flag__c==TRUE){
                a.X__c = b.X__c;  

            }
            else{
                a.X__c = '';
            }


            updatedAList.add(a);
       }
    }

if(!updatedAList.isEmpty()){
    Database.update(updatedAList);
}
} 
}

Best Answer

Since you are running the for loop on both B and A object records, the same A record can be repeatedly added to the list which is causing the error during the update.

you can either add the A records to be updated into a map by checking if it already added or not and then update the records or

you can optimize it further by storing the value of field X__c in a map against the code__c as a key and running the for loop only once on the queried A records and directly updating the same list

trigger UpdateXField on B__c (after insert,after update){

Map<String,String> bCodeXMap = new Map<String,String>();

for(B__c b:Trigger.New){
    if(b.Status__c=='Approved' && b.Flag__c==TRUE)
      bCodeXMap.put(b.Code__c,b.X__c);
}

List<A__c> AList = [SELECT BCode__c,X__c FROM A__c 
                                WHERE RecordType.Name = 'Test' AND BCode__c IN: bCodeXMap.keySet()  LIMIT : Limits.getLimitQueryRows() - Limits.getQueryRows()];

if(!AList.isEmpty()){                                
        for(A__c a:aList){
            if(bCodeXMap.containsKey(a.BCode__c)){
                a.X__c = bCodeXMap.get(a.BCode__c);      
            }
       }
       Database.update(AList);
    }    

}