如何使用LINQ合并三个产品关联列表并解决查询结果重复问题
重复行产生原因
你当前的写法会触发笛卡尔积问题:如果某个产品有N个关联Leaflet、M个关联Label,左连接后会生成N*M行数据,这就是异常重复的来源。
解决方案
根据你的实际业务需求可以选择两种处理方式:
方案1:单产品仅返回一行(推荐,无重复)
如果不需要将多个Leaflet/Label拆分为多行,直接将同产品的关联值聚合即可:
PMatrix = (from a in AllProducts join b in Leaflets on a.Product equals b.Product into b_grp join c in Labels on a.Product equals c.Product into c_grp select new ProductMatrixModel { Product = a.Product, // 多值用逗号拼接,无匹配则返回空字符串 Leaflet = string.Join(",", b_grp.Select(x => x.Leaflet)), Label = string.Join(",", c_grp.Select(x => x.Label)) }).ToBindableCollection();
如果你的模型需要存储集合而非拼接字符串,把属性改为List<string>类型后直接返回b_grp.Select(x => x.Leaflet).ToList()即可。
方案2:多值拆分为多行,无冗余重复
如果确实需要把每个Leaflet/Label拆分为独立行,先对同产品的两个关联集合按索引对齐,避免笛卡尔积:
PMatrix = AllProducts.SelectMany(a => { // 获取当前产品的所有Leaflet,无匹配则默认空字符串 var leafletList = Leaflets.Where(b => b.Product == a.Product) .Select(b => b.Leaflet) .DefaultIfEmpty("") .ToList(); // 获取当前产品的所有Label,无匹配则默认空字符串 var labelList = Labels.Where(c => c.Product == a.Product) .Select(c => c.Label) .DefaultIfEmpty("") .ToList(); // 对齐两个集合的长度 var maxLen = Math.Max(leafletList.Count, labelList.Count); while(leafletList.Count < maxLen) leafletList.Add(""); while(labelList.Count < maxLen) labelList.Add(""); // 按索引生成行,不会产生冗余笛卡尔积 return Enumerable.Range(0, maxLen).Select(i => new ProductMatrixModel { Product = a.Product, Leaflet = leafletList[i], Label = labelList[i] }); }).ToBindableCollection();
内容的提问来源于stack exchange,提问作者Formant
相关产品推荐
相关产品推荐

