[Tips] SOQLの結果からId型のリストを抽出する を改良して、子リレーションのId項目も抽出できるようにしました。
public class FieldSlice {
private list<Object> olist;
public FieldSlice(list<Object> olist) {
this.olist = olist;
}
/**
* 指定したIdフィールドのリストを返す
* @param idFieldName Idフィールド名
* @return 指定したIdフィールドのリスト
*/
public List<Id> retrieveIds(String idFieldName) {
return retrieveIds(idFieldName, null);
}
/**
* 指定したIdフィールドのリストを返す
* @param idFieldName Idフィールド名
* @param childRelationName 子リレーションから取得する場合に指定する子リレーション名
* @return 指定したIdフィールドのリスト
*/
public List<Id> retrieveIds(String idFieldName, String childRelationName) {
List<Id> ids = new List<Id>();
for ( Object obj : olist ) {
String s = JSON.serialize(obj);
Map<String,Object> m = (Map<String,Object>)JSON.deserializeUntyped(s);
if ( String.isEmpty(childRelationName) ) {
// nullは結果から除外
if ( (Id)m.get(idFieldName) != null ) {
ids.add((Id)m.get(idFieldName));
}
} else {
// 子リレーションから取得
Map<String,Object> childRelation = (Map<String, Object>)m.get(childRelationName);
List<Object> children = (List<Object>)childRelation.get('records');
ids.addAll(new FieldSlice(children).retrieveIds(idFieldName));
}
}
return ids;
}
}
使い方は次の通り。
List<Account> accounts = [
SELECT
Id,
(
SELECT
Id
FROM
Contacts
)
FROM
Account
];
// ここで取引先のIdを取得(従来の使い方でそのまま使える)
List<Id> accountIds = new FieldSlice(accounts).retrieveIds('Id');
// 子の取引先責任者のIdを取得 <= New!
List<Id> contactIds = new FieldSlice(accounts).retrieveIds('Id', 'Contacts');
とっても楽ちんです。