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

Why can't I have a Map<Id, Integer> ?

According to SFC documentation "values can be a primitive". An Integer is a primitive.


I am building a trigger that requires me to do a check on how many Circuits have already been defined. If the user is defining the first circuit, all fields are required. I had the count in a for loop and it works fine until I break the bulk trigger rules with Too many SOQL queries


Integer mycount  = [select count() from Circuit__c where Device__c = :circ.Device__c];


So I thought I would put the count in a Map and correlate it to an Id.


Map<Id, Integer> circCountMap = new Map<Id, Integer>
   ([SELECT count() FROM Circuit__c WHERE Device__c in:devIds]);


But when I try to save, I get an error

Error: Compile Error: Invalid initial type Integer for MAP:Id,String at line 13 column 35 


Why can't I do this? And does anybody have a suggestion for how I can get the counts so I can check each Circuit being inserted?


Thank you


According to this documentation you can only define maps where the first parameter, the key must be of the type Id or String, and each one must be unique and distinct from others


I have a feeling that you might want to use an AggregateResult. Can you post the rest of the trigger so we can see it in context?


Thank you for all the responses. Below is the original trigger and the count() query is inside the for loop and causes problems on bulks.


trigger circuitBeforeTrigger on Circuit__c (before delete, before insert, before update) {
    //Set for Master Ids
    Set<Id> devIds = new Set<Id>();
    for (Circuit__c circ : {  
         //Load the Ids Set from this object ref. to the Master              
   Map<Id, Device__c> devMap = new Map<Id, Device__c>
       ([SELECT Site__r.Company_I__r.Status__c, Device_Type__c FROM Device__c WHERE Id in:devIds]); 
   for (Circuit__c circ : { 
       String compStatus = devMap.get(circ.Device__c).Site__r.Company_I__r.Status__c;
       String devType = devMap.get(circ.Device__c).Device_Type__c;
       System.debug('compStatus = ' + compStatus);  
       if (compStatus == 'Pending'){
           circ.addError('A Circuit record may not be updated while Onboard Review is in Pending        status');
       else {      
           if (!Trigger.isDelete) {
                Boolean deviceOk = false;
                if (devType == 'ROUTER'){
                    deviceOk = true;
                    Integer mycount  = [select count() from Circuit__c where Device__c = :circ.Device__c];
                    if ( mycount < 1 ) {
                        // Test all fields for null
                        Integer c = 0;
                        if ( circ.Carrier_Phone__c  == Null ){ c++;}
                        if ( circ.Carrier_Provider__c  == Null ){c++;}
                        if ( circ.Circuit_Id__c == Null ) {c++;}
                        if ( circ.Circuit_Interface__c == Null ) {c++;}
                        if ( circ.Circuit_Type__c == Null ) {c++;}
                        if ( c > 0 )
                            circ.addError('All fields are required if device type is a Router and this is the first circuit defined');
                    }//end mycount
                }//end if Router
                if (devType == 'SWITCH') {deviceOk = true;}
                if (devType == 'OTHER')  {deviceOk = true;}
                if (devType == 'RADIO' ) {deviceOk = true;} 
                if ( !deviceOk )
                    System.debug('devtype = ['+devType+']');
                    circ.addError('A circuit is not applicable for a '+devType+' device type');
                }//end deviceok check
   }//end for



A few things.


1. You can have a Map<Id, Integer>, the problem is that the auto map constructor from SOQL statements is always Id -> record type.


2 your select count() query will only ever return one row, so this is not generating the data set you think it is.


As others as suggested, you'll need to use an aggreage query, and build the map yourself, something like

Map<Id, Integer> counts = new Map<Id, Integer>();

for (AggregateResult r : [select device__c, count(device__c)  cnt from circuit__c where device__c in :devIds group by device__c]) {

   counts.put(r.get('device__c'), r.get('cnt'));




Hi Simon,

That looked really promising but throws a compilation error


Error: Compile Error: Invalid type: AggregateResult at line 14 column 4


I then tried a variation of that as documented in Apex guide but got similar results. Here was the other way I tried



AggregateResult[] r = [select device__c, count(device__c) cnt from circuit__c  where device__c in :devIds group by device__c]; 



Make sure your Apex Code is set to v18.