.NET中使用LINQ合并列表未保留全部模板项的问题
问题原因
你使用的Join是内连接,它只会返回两个列表中满足匹配条件的交集记录——也就是只有那12条和records匹配的template记录会被保留,所以最终输出只有12条,而非你期望的全部50条。
解决方案
有两种常用方式实现你的需求:
方式一:直接更新原列表后返回
先遍历template,匹配records中的对应项并更新IncValue,最后直接返回整个template列表(如果不想修改原template,可以先克隆所有对象):
// 更新匹配项的IncValue foreach (var templateItem in template) { var matchedRecord = records.FirstOrDefault(r => r.Product == templateItem.Product && r.OriginYear == templateItem.OriginYear && r.DevelopmentYear == templateItem.DevelopmentYear); if (matchedRecord != null) { templateItem.IncValue = matchedRecord.IncValue; } } // 此时template已包含所有50条更新后的记录 var output = template.ToList();
方式二:用LINQ左连接保留所有记录
通过GroupJoin配合SelectMany实现左连接,保留template的所有记录,同时匹配更新IncValue:
var output = template.GroupJoin(records, t => new { t.Product, t.OriginYear, t.DevelopmentYear }, r => new { r.Product, r.OriginYear, r.DevelopmentYear }, (t, matchedRecords) => new { TemplateItem = t, Matches = matchedRecords }) .SelectMany(x => x.Matches.DefaultIfEmpty(), (x, matchedRecord) => { // 若存在匹配项则更新,否则保留原数值 if (matchedRecord != null) { x.TemplateItem.IncValue = matchedRecord.IncValue; } return x.TemplateItem; }) .ToList();
不修改原对象的版本
如果不想改动原template的对象实例,可以创建新的InputRecord对象返回:
var output = template.GroupJoin(records, t => new { t.Product, t.OriginYear, t.DevelopmentYear }, r => new { r.Product, r.OriginYear, r.DevelopmentYear }, (t, matchedRecords) => new { TemplateItem = t, Matches = matchedRecords }) .SelectMany(x => x.Matches.DefaultIfEmpty(), (x, matchedRecord) => new InputRecord { Product = x.TemplateItem.Product, OriginYear = x.TemplateItem.OriginYear, DevelopmentYear = x.TemplateItem.DevelopmentYear, IncValue = matchedRecord?.IncValue ?? x.TemplateItem.IncValue }) .ToList();
内容的提问来源于stack exchange,提问作者Vax
相关产品推荐
相关产品推荐

