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());
}
}
它可能包含一些拼写错误,但这是一个普遍的想法。
我是 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());
}
}
它可能包含一些拼写错误,但这是一个普遍的想法。