如何高效关联两个API返回的Customer与Town数据?
优化客户与城镇数据关联的高效实现方案
核心优化思路
原来的遍历匹配方式,每次给客户找对应城镇都要扫一遍整个城镇列表,数据量一大效率就很低。我们可以把城镇列表转换成以townId为键的字典,这样查找操作的时间复杂度直接降到O(1),不仅速度快,还能把关联逻辑封装起来,在多个业务场景复用。
优化后的基础实现代码
List<Customer> customers = new List<Customer> { new Customer { Id = 1, Name = "First Customer", townId = 10 }, new Customer { Id = 2, Name = "Second Customer", townId = 20 }, new Customer { Id = 3, Name = "Third Customer", townId = 20 } }; List<Town> towns = new List<Town> { new Town { townId = 10, townName = "Eton" }, new Town { townId = 20, townName = "Harrow" }, new Town { townId = 30, townName = "Cambridge" } }; // 先把城镇列表转成字典,键为townId,值为对应的Town对象 var townLookup = towns.ToDictionary(t => t.townId); // 批量关联客户与城镇 foreach (var customer in customers) { // 用TryGetValue避免因不存在的townId抛出异常,同时获取匹配的城镇 townLookup.TryGetValue(customer.townId, out var matchedTown); customer.town = matchedTown; }
封装成可复用的逻辑
为了避免在多个业务场景重复写相同的关联代码,可以把逻辑封装成扩展方法或者通用工具类:
针对Customer的扩展方法
public static class CustomerExtensions { public static void LinkWithTowns(this List<Customer> customers, List<Town> towns) { var townDict = towns.ToDictionary(t => t.townId); foreach (var customer in customers) { townDict.TryGetValue(customer.townId, out var town); customer.town = town; } } } // 调用的时候直接用: customers.LinkWithTowns(towns);
通用关联工具类(支持更多类似场景)
如果你的系统里还有其他类似的“通过ID关联两个集合”的需求,可以写一个更通用的工具方法:
public static class DataLinkHelper { public static void LinkEntities<TMain, TRelated, TKey>( IEnumerable<TMain> mainEntities, IEnumerable<TRelated> relatedEntities, Func<TMain, TKey> mainKeyGetter, Func<TRelated, TKey> relatedKeyGetter, Action<TMain, TRelated> linkAction) { var relatedDict = relatedEntities.ToDictionary(relatedKeyGetter); foreach (var mainEntity in mainEntities) { var key = mainKeyGetter(mainEntity); relatedDict.TryGetValue(key, out var relatedEntity); linkAction(mainEntity, relatedEntity); } } } // 调用示例: DataLinkHelper.LinkEntities( customers, towns, customer => customer.townId, town => town.townId, (customer, town) => customer.town = town);
方案优势
- 效率高:字典的键查找是O(1)操作,数据量越大,对比原遍历方案的性能提升越明显。
- 可复用:封装后无需重复编写关联逻辑,直接调用即可。
- 更安全:使用
TryGetValue替代直接索引字典,避免因无效townId抛出KeyNotFoundException。
内容的提问来源于stack exchange,提问作者SkinnyPete63
相关产品推荐
相关产品推荐

