Triggers 如何创建Apex类?

Triggers 如何创建Apex类?,triggers,salesforce,apex,test-class,Triggers,Salesforce,Apex,Test Class,通过大量的尝试和错误,我在沙盒中创建了功能正常的触发器。我的问题是,我现在想把它应用到我的live组织中,但我似乎无法理解整个apex类的事情 如何创建类 我的触发器背后的想法是当一个机会记录被保存时,soql查询将查看在“类别”字段中选择的选取列表值,并找到具有匹配名称的活动供应商或成员服务帐户类型,并将其salesforce id带出。将该sfid拖到“我的供应商名称查找”字段中,将允许我在我创建的opportunity和供应商/成员服务帐户之间建立关系需要其他工作流规则和字段更新

通过大量的尝试和错误,我在沙盒中创建了功能正常的触发器。我的问题是,我现在想把它应用到我的live组织中,但我似乎无法理解整个apex类的事情

如何创建类

我的触发器背后的想法是当一个机会记录被保存时,soql查询将查看在“类别”字段中选择的选取列表值,并找到具有匹配名称的活动供应商或成员服务帐户类型,并将其salesforce id带出。将该sfid拖到“我的供应商名称查找”字段中,将允许我在我创建的opportunity和供应商/成员服务帐户之间建立关系需要其他工作流规则和字段更新

    trigger Find_Vendor on Opportunity (before insert)
    {
       for(Opportunity u:trigger.new)
       {
          if(u.Vendor_Name__c == null)
          {
              u.Vendor_Name__c =   [Select Id From Account
                             Where (Account_Type__c = 'Vendor'
                             OR Account_Type__c = 'Member Services')
                             AND Status__c = 'Active'
                             AND Name = :u.Category__c limit 1].Id;
          }
       }
    }

在建议您将代码部署到live org之前,我想指出代码中的一些问题

  • 您正在for cycle中使用SOQL语句。在SF环境中,每个事务只能执行101个SOQL查询。当您对OPP进行大规模更新时,可能会超过101个OPP,您将遇到SOQL限制:查询太多

  • 为了能够部署到生产orrg,您需要有测试覆盖率。因此,为了能够将此触发器部署到生产环境中,您需要创建一个测试。不要忘记运行一些批量测试

  • 我建议您不要使用触发器来实际执行功能。你的组织中会有大量的触发器,你很难管理触发器的执行顺序。尝试采用触发器不包含任何逻辑的模型,除了是否在更新之前或之后等等。可以找到基本的解释


  • 了解更多关于SF限制和最佳实践的一个很好的资源是。

    我不会将此触发器部署到生产环境中。它有许多问题,可能会中断,因为您在for循环中执行SOQL查询,而且逻辑似乎没有经过很好的考虑。鉴于您似乎不太精通编写触发器,您可能应该考虑一种声明性解决方案,例如和,在其中您可以实现相同的结果。如果您坚持使用触发器,我建议您使用以下内容:

     trigger Find_Vendor on Opportunity (before insert)
    {
       Set<String> categories = new Set<String>();
       Map<String, Id> categoryAccountIdMap = new Map<String, Id>();
       for(Opportunity u:trigger.new)
       {
          if(u.Category__c != null)
          {
               categories.add(u.Category__c);
          }
       }
       List<Account> categoryAccounts = [Select Id From Account
                             Where (Account_Type__c = 'Vendor'
                             OR Account_Type__c = 'Member Services')
                             AND Status__c = 'Active'
                             AND Name IN :categories];
       for(Account acct : categoryAccounts){
           if(!categoryAccountIdMap.containsKey(acct.Name)){
                categoryAccountIdMap.put(acct.name, acct.Id);
           }
       }
       for(Opportunity u:trigger.new)
       {
          if(u.Vendor_Name__c == null && categoryAccountIdMap.containsKey(u.Category__c))
          {
              u.Vendor_Name__c =   categoryAccountIdMap.get(u.Category__c);
          }
       }
    }
    

    也就是说,有许多最佳实践没有在这里使用,例如测试数据工厂和将业务逻辑从触发器移动到您应该熟悉的域类中。

    那么您的触发器是否按预期工作?我知道你现在想把它从你的测试组织放到你的生活组织中,对吗?@utm没错。只是试着把它从测试组织带到活动组织。所以关键是你不能直接在活动组织中部署一些东西。必须使用变更集。为此,您的测试组织必须与您的live组织连接。如果这样做了,您可以创建出站变更集,其中包含测试组织中的所有变更(类等)。然后必须上载此变更集,并且在另一个组织(活动组织)上可以导入此变更集(入站变更集)。我建议阅读/执行“使用变更集从沙箱部署”的入门教程
    @IsTest
    private class SomeTestClassName {
    
    @isTest
    static void testOppVendor() {
     //you may need to add required fields to these objects to actually insert  them
        Account a = new Account(Name = 'Category 1');
        insert  a;
        Opportunity o = new Opportunity(Name = 'test', StageName = 'Closed Won', Category__c = 'Category 1');
        insert o;
        o = [SELECT Vendor_Name__c FROM Opportunity where Id = :o.Id];
        System.assertEquals(a.Id, o.Vendor_Name__c);
    }