C#四层嵌套列表处理:仅添加Coupons列表非空的关联元素
问题背景
现有四层嵌套列表结构,层级由外到内依次为Companies、Shops、Campaigns、Coupons,所有数据均从服务端拉取。需要实现过滤规则:仅当最内层Coupons列表非空时,才将对应的关联层级元素添加到结果列表,过滤所有Coupons为空的无效数据。
原有业务实现代码如下:
foreach (var row in Companies) { reportData.companies.Add(new Companies { ID = row.Id, name = row.BrandName }); var Shops = logicService.CompanyShopService.GetShopsByCompany(row.Id); var Campaigns = logicService.CampaignService.GetCampaignsByCompany(row.Id); foreach (var shop in Shops) { reportData.companies.Where(item => item.ID == shop.ClientID).FirstOrDefault().shops.Add(new Distribution_Shops { Id = shop.Id, Name = shop.Name }); var shop_campaigns = Campaigns.Where(item => item.ShopID == shop.Id); foreach (var campaign in shop_campaigns) { var coupons = logicService.CouponsService.GetAllByCampaign(campaign.Id, false); foreach (var company in reportData.companies) { foreach (var tmp_shop in company.shops) { if (tmp_shop.Id == shop.Id) { tmp_shop.campaigns.Add(new Distribution_Campaign { Id = campaign.Id, Name = campaign.CampaignName, coupons = coupons}); } } } } } }
原有代码缺陷
- 先添加Company、Shop节点后再补Campaign数据,会残留大量Coupons为空的无效Shop、Company节点,达不到过滤要求
- 存在多层冗余全量遍历:每次添加Campaign时都循环所有已加入的Company和Shop,数据量较大时性能损耗明显
- 未做Coupons非空判断,空Coupons对应的Campaign、关联的Shop和Company都会被错误加入结果集
- 缺少空值校验,
FirstOrDefault()可能返回null值,直接调用shops.Add会触发空引用运行时错误
优化实现方案
核心逻辑为从最内层数据开始校验,只有内层存在有效非空数据时,才构造外层对应节点加入结果,从根源避免无效数据进入结果集,无需后续二次过滤。
foreach (var companyRow in Companies) { // 预拉取当前公司下关联的所有门店、活动数据 var shops = logicService.CompanyShopService.GetShopsByCompany(companyRow.Id); var allCompanyCampaigns = logicService.CampaignService.GetCampaignsByCompany(companyRow.Id); var validCompany = new Companies { ID = companyRow.Id, name = companyRow.BrandName }; bool companyHasValidData = false; foreach (var shop in shops) { var validShop = new Distribution_Shops { Id = shop.Id, Name = shop.Name }; bool shopHasValidCampaign = false; // 筛选当前门店绑定的所有活动 var shopCampaigns = allCompanyCampaigns.Where(c => c.ShopID == shop.Id); foreach (var campaign in shopCampaigns) { // 拉取活动下的优惠券,仅非空时保留该活动 var coupons = logicService.CouponsService.GetAllByCampaign(campaign.Id, false); if (coupons != null && coupons.Any()) { validShop.campaigns.Add(new Distribution_Campaign { Id = campaign.Id, Name = campaign.CampaignName, coupons = coupons }); shopHasValidCampaign = true; } } // 门店下存在带有效优惠券的活动时,才将门店加入公司节点 if (shopHasValidCampaign) { validCompany.shops.Add(validShop); companyHasValidData = true; } } // 公司下存在有效门店数据时,才将公司加入最终结果集 if (companyHasValidData) { reportData.companies.Add(validCompany); } }
方案优势
- 过滤逻辑从最内层Coupons触发,只有Coupons非空才会逐层向上添加关联的Campaign、Shop、Company节点,完全过滤无效链路数据
- 移除了原有代码中多层嵌套的冗余遍历,构造节点时直接挂载到对应父级,执行效率更高
- 增加了空值判断,避免空引用异常
- 通过布尔标记位记录每层有效数据状态,不需要对结果集做二次遍历清理
内容的提问来源于stack exchange,提问作者Arthur
相关产品推荐
相关产品推荐

