在C#中如何将账户记录列表转换为无限层级树形结构?
账户层级数据转换需求与实现
我们当前接收的账户列表包含可选的父账户ID。在数据导入过程中发现,账户的父子关系比预期更为复杂,许多层级可达3-4层,部分层级链甚至高达7层。
我们需要将源账户数据转换为包含子记录列表的对象,且这些子记录也可拥有自己的子记录,以此类推形成无限层级结构。
定义的数据结构
源数据类
public class AccountSourceData { public int Id { get; set; } public string Name { get; set; } public int? ParentId { get; set; } }
目标数据类
public class AccountTransformedData { public int Id { get; set; } public string Name { get; set; } public List<AccountTransformedData> ChildAccounts { get; set;} }
需要实现的转换方法框架
public List<AccountTransformedData> TransformAccountData(List<AccountSourceData> srcAccounts) { List<AccountTransformedData> accounts = new List<AccountTransformedData>(); foreach (var parentAccount in srcAccounts.Where(t => !t.ParentId.HasValue)) { .... .. .... } return accounts; }
转换结果示例
转换后的结果应为父账户列表,每个父账户包含子账户列表,子账户也可嵌套子账户,示例如下:
parent account 1 --- child account List -------child account 1 ---------- child account List -------child account 2 ---------- child account List ---------------grandchild account 1 ------------------ grandchild account List parent account 2 --- child account List -------child account 1 ---------- child account List -------child account 2 ---------- child account List ---------------grandchild account 1 ------------------ grandchild account List
完整实现方案
递归实现方式
适合层级不超递归深度限制的场景,代码简洁直观:
public List<AccountTransformedData> TransformAccountData(List<AccountSourceData> srcAccounts) { // 构建ID到源数据的映射字典,提升查找效率 var accountDict = srcAccounts.ToDictionary(a => a.Id); var result = new List<AccountTransformedData>(); // 遍历所有顶级账户(无父ID) foreach (var srcAccount in srcAccounts.Where(a => !a.ParentId.HasValue)) { result.Add(BuildAccountHierarchy(srcAccount, accountDict)); } return result; } private AccountTransformedData BuildAccountHierarchy(AccountSourceData srcAccount, Dictionary<int, AccountSourceData> accountDict) { // 转换当前账户 var transformedAccount = new AccountTransformedData { Id = srcAccount.Id, Name = srcAccount.Name, ChildAccounts = new List<AccountTransformedData>() }; // 查找当前账户的所有子账户并递归构建层级 foreach (var childSrc in accountDict.Values.Where(a => a.ParentId == srcAccount.Id)) { transformedAccount.ChildAccounts.Add(BuildAccountHierarchy(childSrc, accountDict)); } return transformedAccount; }
迭代实现方式
避免递归深度限制问题,适合极深层级的场景:
public List<AccountTransformedData> TransformAccountData(List<AccountSourceData> srcAccounts) { var accountDict = srcAccounts.ToDictionary(a => a.Id); var transformedDict = new Dictionary<int, AccountTransformedData>(); var result = new List<AccountTransformedData>(); // 先将所有源账户转换为目标对象存入字典 foreach (var srcAccount in srcAccounts) { transformedDict[srcAccount.Id] = new AccountTransformedData { Id = srcAccount.Id, Name = srcAccount.Name, ChildAccounts = new List<AccountTransformedData>() }; } // 遍历账户,将子账户挂载到对应父账户下 foreach (var srcAccount in srcAccounts) { if (srcAccount.ParentId.HasValue && transformedDict.TryGetValue(srcAccount.ParentId.Value, out var parent)) { parent.ChildAccounts.Add(transformedDict[srcAccount.Id]); } else { // 无父ID的顶级账户直接加入结果列表 result.Add(transformedDict[srcAccount.Id]); } } return result; }
内容的提问来源于stack exchange,提问作者chris
相关产品推荐
相关产品推荐

