【问题标题】:Salesforce APEX method not bulkifiedSalesforce APEX 方法未批量化
【发布时间】:2018-11-18 05:19:42
【问题描述】:

我编写了一个 APEX 类,它会在客户端发布时发送电子邮件。有一种方法我认为我已经扩大了,但我被告知它没有。这是因为此方法调用了另一个函数,该函数实际上执行了实际的电子邮件创建并且没有被批量化。有人可以指导我如何从方法中取出 SOQL 查询吗?

global class LM_ChangeAccountRT {

    private static final Profile sysAdmin = [select id from profile where name='System Administrator'];

@AuraEnabled
    public static String resendEmails(List<String> accountIdList) {
        String response = null;
        try {
            //Only send emails if user is either an ARMS Administor or System Administrator
            if (System.label.ARMS_Administrator_Profile_Id == userinfo.getProfileId() || 
                sysAdmin.Id == userinfo.getProfileId()) {
                List<Account> accList = [SELECT Id,Client_Released__c, RecordTypeId,Client_Number__c, Client_Released__c, Email_Sent__c FROM Account WHERE Id IN:accountIdList];

                for(Account acc: accList){
                    if (acc.Client_Number__c != null && acc.Client_Released__c && acc.Email_Sent__c == true) {
                        sendpdfgenerationEmails(acc); //this is the method thats not bulkified.
                        acc.Email_Sent__c = false; 

                        response = 'Email Sent';
                    }else {
                        response= 'Access Denied';
                    }
                }

                    update accList;
            }  
        }catch(Exception e) {
            System.debug(e.getMessage());
            response = 'Error sending emails';
        }
        return response;
    }

 public static void sendpdfgenerationEmails(Account acc){
        system.debug('start of confirmation card and pdf generation');
        //Logic to find which VF template is used to send an email.
        list<EmailTemplate> templateId = new list<EmailTemplate>();  
        string temppartner;
        String partner_opt_in_attachment;
        boolean sendFCAmail;

        List<Dealership_PDF_Generation__c> custsettingdata = Dealership_PDF_Generation__c.getall().values();
        System.debug('custom setting size = ' + custsettingdata.size());
        // Fetch State
        if(acc.Dealership_State__c!=null && acc.Dealership_Partner__c!=null)
        {
            for(Dealership_PDF_Generation__c tempcustsetting :custsettingdata)

            {   
                if(acc.Dealership_Partner__c == tempcustsetting.Dealership_Partner__c && acc.Dealership_State__c==tempcustsetting.State__c  && tempcustsetting.State__c=='WA' && acc.Dealership_State__c=='WA'){

                    //For WA State
                    // temppartner= '%' + tempcustsetting.TEMPLATE_Unique_name__c + '%';
                    temppartner= tempcustsetting.TEMPLATE_Unique_name__c;
                    if(acc.Dealership_Spiff_Payment__c == '% premium'){
                        partner_opt_in_attachment=tempcustsetting.opt_in_form_premium__c;
                    }else{
                        partner_opt_in_attachment=tempcustsetting.opt_in_form_nonpremium__c;
                    }
                } 
                else if(acc.Dealership_Partner__c == tempcustsetting.Dealership_Partner__c && acc.Dealership_State__c==tempcustsetting.State__c  && tempcustsetting.State__c=='TX' && acc.Dealership_State__c=='TX'){
                    //For TX State 
                    //temppartner= '%' + tempcustsetting.TEMPLATE_Unique_name__c + '%'; 
                    temppartner= tempcustsetting.TEMPLATE_Unique_name__c;
                    if(acc.Dealership_Spiff_Payment__c == '% premium'){
                        partner_opt_in_attachment=tempcustsetting.opt_in_form_premium__c;
                    }else{
                        partner_opt_in_attachment=tempcustsetting.opt_in_form_nonpremium__c;
                    }
                }
                else if(acc.Dealership_Partner__c == tempcustsetting.Dealership_Partner__c && acc.Dealership_State__c!=tempcustsetting.State__c && tempcustsetting.State__c!='TX' && acc.Dealership_State__c!='TX' && acc.Dealership_State__c!='WA' &&tempcustsetting.State__c!='WA' ){
                    //For Non TX State
                    //temppartner= '%' + tempcustsetting.TEMPLATE_Unique_name__c + '%';
                    temppartner= tempcustsetting.TEMPLATE_Unique_name__c;
                    if(acc.Dealership_Spiff_Payment__c == '% premium'){
                        partner_opt_in_attachment=tempcustsetting.opt_in_form_premium__c;
                    }else{
                        partner_opt_in_attachment=tempcustsetting.opt_in_form_nonpremium__c;
                    }
                    system.debug('grabbed template: ' + temppartner);
                }
if(acc.Dealership_Partner__c != null && temppartner!=null ){
            templateId.add([Select id,DeveloperName from EmailTemplate where DeveloperName = :temppartner]); //This will probably cause governor limit issues. First problem

        } 

    if (partner_opt_in_attachment != null) {
                StaticResource sr = [Select  s.Name, s.Id, s.Body From StaticResource s where s.Name =: partner_opt_in_attachment]; //'static_resource' is the name of the static resource PDF. This is another SOQL query that will cause problems

                Blob tempBlob = sr.Body;

                Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
                efa.setBody(tempBlob);
                efa.setFileName('Opt-in.pdf');

                List<Messaging.EmailFileAttachment> attachments = new List<Messaging.EmailFileAttachment>();
                attachments.add(efa);
                // add attachment to each email
                for (Messaging.SingleEmailMessage email : emails) {
                    email.setFileAttachments(attachments);
                }

            }
            system.debug('email sent: ' + emails.size());
            Messaging.sendEmail(emails); 

        }
    } 
}

我之所以尝试对此进行批量处理是因为我编写了一个 APEX 调度程序,它每天早上 7 点调用 resendemails 方法来检查哪些记录需要发送电子邮件。恐怕如果有超过 100 个客户,那么它会导致问题而不发送电子邮件。关于如何优化 sendpdfemailgeenration() 方法的任何建议? 谢谢

【问题讨论】:

    标签: salesforce apex


    【解决方案1】:

    是的,你是对的 - 你的 resendEmails() 方法没有被批量化。


    首先,让我解释一下为什么会这样:

    • SOQL 获取帐户
    • Loop 1 在账户记录列表上
      • 调用sendpdfgenerationEmails()方法
      • 检索 Dealership_PDF_Generation__c 记录列表
      • Loop 2 在 Dealership_PDF_Generation__c 记录列表中
        • 获取静态资源的 SOQL - 非常糟糕!它在双循环内!
        • 调用Messaging.sendEmail()方法 - 非常糟糕!它在双循环内!
    • 帐户记录列表更新

    你需要记住:

    1.你不应该在循环中执行 SOQL! - 每笔交易限制 100 SOQL

    2。你不应该在循环中调用Messaging.sendEmail()! - 每个事务限制 10 调用


    现在让我指导你如何重构这个方法:

    @AuraEnabled
    public static String resendEmails(List<String> accountIdList) {
        // 1. SOQL for List of Account records
        // 2. Retrieve list of Dealership_PDF_Generation__c records
        // 3. SOQL for List of StaticResources for all Names from Dealership_PDF_Generation__c records
        // 4. Declaration of new List variable for Messaging.SingleEmailMessage objects
        // 5. Loop 1 on List of Account records
        //      6. Call new "prepareEmailsForAccount()" method, which prepares and returns list of Messaging.SingleEmailMessage objects
        //      7. Add returned Messaging.SingleEmailMessage objects to list from point 4
        //      8. End of loop 1
        // 9. Call "Messaging.sendEmail()" method with list from point 4
        // 10. Update on List of Account records
    }
    

    这样,您将避免 SOQL 并在循环中调用 Messaging.sendEmail() 方法。

    【讨论】:

    • 嗨 Nobi992,所以在您的指示中,您是说 sendpdfgeneeationpdf 方法需要被批量化吗?还是应该消除 sendpdfgeneration 并将所有内容都放在 resendemails 方法中? resend email 方法调用了 sendpdfgeneration 方法,所以我有点困惑我在批量处理哪个方法。我还不清楚第 6、7、9 点。您有任何示例代码吗?非常感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多