Salesforce Apex Class 使用来自父级的 ID 更新自定义对象查找字段

Salesforce Apex Class update custom object lookup field with id from parent

我是 Apex 的新手,我正在努力创建一个 class 来帮助我进行一些数据分析。我有来自第三方 (transactions__C) 的数据,它有一个字段 (fin_acct_txt__c),它是指向另一个对象 (fin_accounts__C) 的指针。我想用 fin_accounts__C 中的 ID 将 transactions__c 更新到查找字段 transactions__c.fin_acct__c 中。 我想在 class 而不是触发器中执行此操作,因为每月从第 3 方加载的记录数以千计。我认为批量执行此操作会更有效率。 我的想法是为 transactions__c 创建一个列表,为 fin_accounts__c 创建一个地图。使用 fin_acct_txt__c=fin_accounts__c.name 我将能够获取 fin_accounts__c.id 并使用该数据更新 transactions__c.fin_acct__c 。 但是 Apex 的新手似乎给我带来了一些我不确定如何解决的问题。 这是我迄今为止所做的副本:

public class updateTxnFinAcctID {

// Build map of financial accts since that is unique

map<string ,fin_acct__c> finAccts = new map<string, fin_acct__c>
    ([select id,name from fin_acct__c where name!=null]);

//Iterate through the map to find the id to update the transactions
{
for(fin_acct__c finAcct: finAccts.values())
{
    if (finAcct.name != Null)
    {
        finAccts.put(finAcct.name, finAcct);
    }

// Find all records in transaction__c where fin_acct__c is null 
//and the pointer is the name in the map

list<Transaction__c> txns =[
    select id,fin_acct_txt__c from Transaction__c where fin_acct__c = null
    and fin_acct_txt__c=:finaccts[0].name];

//create the list that will be used to update the transaction__c

list <Transaction__c> txnUpdate = new list <Transaction__c>();
{
//Find the id from fin_acct__c where name = fin_acct_txt__c
for (Transaction__c txn: txns){
    finacct[0].Id =txn.fin_acct__c;
    txnUpdate.add(txn);
}
//3. Update transaction with ID

}
}
   // if (txnUpdate.size()>0 { update txnUpdate};
    system.debug(txnUpdate.size());
}
}

我好像陷入了死循环。我得到的错误是“表达式必须是列表类型:映射”指向列表 txns = [ …]。但由于这不是唯一的,所以它必须是列表。但我相信我这里有一些结构性错误,这是一个更大问题的征兆。

谢谢。

我试图了解您的代码应该做什么,我有一些提示,可能它们有助于解决您的问题:

1) 在第一次循环映射 finAccts 的值时,您实际上不需要使用 if (finAcct.name != Null) 进行验证,因为您已经将其添加到 SOQL 查询 (where name!=null) 中。

2) 这是一种不好的做法 - 将其作为键来映射不同的实体(例如,ID 和名称)。我的意思是,当您将 fin_acct__c 查询到映射 finAccts 时,映射的键是 fin_acct__c 的 ID。然后在第一个循环中,您将相同的对象放入同一个映射中,仅使用它们的名称作为键。如果你真的需要这样的地图以名称作为键,最好创建新地图并将数据放在那里。

3) 你执行 SOQL 查询到 Transaction__c 对象进入循环。这很可能是与 SF 限制相关的异常的原因(特别是如果您确定代码将处理大量数据)。最好收集列表中的所有 fin_acct__c 名称并将 SOQL 查询移出循环,在 where 条件中使用 IN 而不是 =

如果我理解正确 fin_acct_txt__c 字段包含名称,而不是 ID,那么您的 class 应该类似于:

public class updateTxnFinAcctID {
    Map<String ,fin_acct__c> finAccts = new Map<String, fin_acct__c>
        ([select id,name from fin_acct__c where Name != null]);

    Map<String, fin_acct__c> finAcctByNames = new Map<String, fin_acct__c>();
    for(fin_acct__c finAcct: finAccts.values()){
        finAcctByNames.put(finAcct.Name, finAcct);
    }

    List<Transaction__c> txns =[select id, fin_acct_txt__c, fin_acct__c
            from Transaction__c where fin_acct__c = null
            and fin_acct_txt__c IN finAcctByNames.keySet()];

    List <Transaction__c> txnUpdate = new List<Transaction__c>();
    for (Transaction__c txn: txns){
        fin_acct__c relatedFinAcct = finAcctByNames.get(txn.fin_acct_txt__c);
        if(relatedFinAcct != null){
            txn.fin_acct__c = relatedFinAcct.Id;
            txnUpdate.add(txn);
        }       
    }   

    if(!txnUpdate.isEmpty()){ 
        update txnUpdate;
        system.debug(txnUpdate.size());
    }
}

它可能包含一些拼写错误,但这是一个普遍的想法。