如何在Salesforce Apex中实现非标准化数据的归一化处理?
解决Salesforce Apex中自定义字段数据归一化问题
问题根源
你的代码错误在于每次循环都新建内部Map<String, String>并直接覆盖外层Map中对应ProductId的条目,导致同一ProductId的多条记录仅保留最后一条的字段值,而非累加所有字段。
修正后的Map实现方案
// 替换为你的实际自定义对象名 List<YourCustomFieldObject__c> rawData = [SELECT ProductId__c, CustomFieldName__c, CustomFieldValue__c FROM YourCustomFieldObject__c]; Map<Id, Map<String, String>> normalizedMap = new Map<Id, Map<String, String>>(); for (YourCustomFieldObject__c record : rawData) { Id productId = record.ProductId__c; String fieldName = record.CustomFieldName__c; String fieldValue = record.CustomFieldValue__c; // 检查当前ProductId是否已有对应的内部Map if (!normalizedMap.containsKey(productId)) { normalizedMap.put(productId, new Map<String, String>()); } // 向已存在的内部Map中添加字段键值对 normalizedMap.get(productId).put(fieldName, fieldValue); }
代码说明
- 遍历原始数据时,先判断外层Map是否存在当前ProductId的内部Map
- 仅当不存在时才新建内部Map,避免覆盖已有数据
- 取出对应内部Map,将当前字段的键值对存入,实现同一ProductId下的字段累加
更直观的自定义类方案
如果需要更清晰的结构化数据(类似对象属性),可以定义自定义类存储归一化结果:
// 定义归一化数据结构类 public class NormalizedProduct { public Id productId; public String firstName; public String lastName; public String phoneNumber; public NormalizedProduct(Id prodId) { productId = prodId; // 初始化字段为null,确保未赋值字段有明确默认值 firstName = null; lastName = null; phoneNumber = null; } } // 处理原始数据 List<YourCustomFieldObject__c> rawData = [SELECT ProductId__c, CustomFieldName__c, CustomFieldValue__c FROM YourCustomFieldObject__c]; Map<Id, NormalizedProduct> normalizedProducts = new Map<Id, NormalizedProduct>(); for (YourCustomFieldObject__c record : rawData) { Id productId = record.ProductId__c; String fieldName = record.CustomFieldName__c; String fieldValue = record.CustomFieldValue__c; if (!normalizedProducts.containsKey(productId)) { normalizedProducts.put(productId, new NormalizedProduct(productId)); } NormalizedProduct target = normalizedProducts.get(productId); // 根据字段名匹配赋值 switch on fieldName { when 'firstName' target.firstName = fieldValue; when 'lastName' target.lastName = fieldValue; when 'phoneNumber' target.phoneNumber = fieldValue; // 可扩展更多字段的case分支 } } // 转换为List方便后续业务处理 List<NormalizedProduct> resultList = normalizedProducts.values();
方案优势
- 类型安全,避免字符串键的拼写错误
- 结构清晰,后续扩展字段只需修改类和switch分支
- 直接得到具有明确属性的对象,便于后续逻辑处理
内容的提问来源于stack exchange,提问作者Geebee
相关产品推荐
相关产品推荐

