英文:
Join two lists in .NET while maintaining single property
问题
在.NET中,我有两个相同的列表,每个项的结构如下:
public class InputRecord
{
public string Product { get; set; }
public int OriginYear { get; set; }
public int DevelopmentYear { get; set; }
public decimal IncValue { get; set; }
}
我尝试使用LINQ来连接这两个记录列表,并在其他属性都匹配的情况下更新IncValue
。我的代码如下:
var output = template.Join(records,
t => new { t.Product, t.OriginYear, t.DevelopmentYear },
r => new { r.Product, r.OriginYear, r.DevelopmentYear },
(t, r) => { t.IncValue = r.IncValue; return t; }).ToList();
template
包含大约50个记录,而 records
包含12个条目。我期望输出会有50个记录,其中 IncValue
在其他属性匹配的情况下被更新,但实际输出只有12个记录。我做错了什么?
英文:
I have two identical lists in .NET, this is how single item looks like:
public class InputRecord
{
public string Product { get; set; }
public int OriginYear { get; set; }
public int DevelopmentYear { get; set; }
public decimal IncValue { get; set; }
}
I'm trying to join two lists of these records using LINQ while updating IncValue where all other properties matches. My code looks like that:
var output = template.Join(records,
t => new { t.Product, t.OriginYear, t.DevelopmentYear },
r => new { r.Product, r.OriginYear, r.DevelopmentYear },
(t, r) => { t.IncValue = r.IncValue; return t; }).ToList();
Template contains about 50 records, while records contains 12 entries. I expect the output to have 50 records with IncValue updated where all other properties matched, however my output is only 12 records. What I'm doing wrong?
答案1
得分: 1
不要使用"join",因为它只返回在两个输入序列中都有匹配键的匹配项,你可以尝试在两个集合之间使用"group join" 操作。
var output = template
.GroupJoin(
records,
t => new { t.Product, t.OriginYear, t.DevelopmentYear },
r => new { r.Product, r.OriginYear, r.DevelopmentYear },
(t, rs) => {
var record = rs.FirstOrDefault();
if (record != null) {
t.IncValue = record.IncValue;
}
return t;
})
.ToList();
GroupJoin 方法通过将左侧列表(template)的元素与右侧列表(records)中匹配的元素进行分组来执行左外连接。
我在.NET Fiddle中使用了以下两个集合进行了测试:
// 定义模板和记录集合
var template = new List<Item>()
{
new Item() { Product = "A", OriginYear = 2018, DevelopmentYear = 1, IncValue = 100 },
new Item() { Product = "A", OriginYear = 2018, DevelopmentYear = 2, IncValue = 200 },
new Item() { Product = "B", OriginYear = 2019, DevelopmentYear = 1, IncValue = 300 },
new Item() { Product = "B", OriginYear = 2019, DevelopmentYear = 2, IncValue = 400 }
};
var records = new List<Item>()
{
new Item() { Product = "A", OriginYear = 2018, DevelopmentYear = 2, IncValue = 250 },
new Item() { Product = "B", OriginYear = 2019, DevelopmentYear = 1, IncValue = 350 },
new Item() { Product = "C", OriginYear = 2020, DevelopmentYear = 1, IncValue = 500 }
};
输出的项目是:
Product: A, OriginYear: 2018, DevelopmentYear: 1, IncValue: 100
Product: A, OriginYear: 2018, DevelopmentYear: 2, IncValue: 250
Product: B, OriginYear: 2019, DevelopmentYear: 1, IncValue: 350
Product: B, OriginYear: 2019, DevelopmentYear: 2, IncValue: 400
如果这不是你需要的结果,我建议分享一些示例数据。
英文:
Instead of using "join
" which will only return matching items that have matching keys in both input sequences, can you try using the "group join
" operation between two collections instead
var output = template
.GroupJoin(
records,
t => new { t.Product, t.OriginYear, t.DevelopmentYear },
r => new { r.Product, r.OriginYear, r.DevelopmentYear },
(t, rs) => {
var record = rs.FirstOrDefault();
if (record != null) {
t.IncValue = record.IncValue;
}
return t;
})
.ToList();
The GroupJoin method performs a left outer join by grouping the elements from the left list (template) with the matching elements from the right list (records).
I played around in .NET Fiddle using the following 2 collections
// Define the template and records collections
var template = new List<Item>()
{
new Item() { Product = "A", OriginYear = 2018, DevelopmentYear = 1, IncValue = 100 },
new Item() { Product = "A", OriginYear = 2018, DevelopmentYear = 2, IncValue = 200 },
new Item() { Product = "B", OriginYear = 2019, DevelopmentYear = 1, IncValue = 300 },
new Item() { Product = "B", OriginYear = 2019, DevelopmentYear = 2, IncValue = 400 }
};
var records = new List<Item>()
{
new Item() { Product = "A", OriginYear = 2018, DevelopmentYear = 2, IncValue = 250 },
new Item() { Product = "B", OriginYear = 2019, DevelopmentYear = 1, IncValue = 350 },
new Item() { Product = "C", OriginYear = 2020, DevelopmentYear = 1, IncValue = 500 }
};
The items in the output was
Product: A, OriginYear: 2018, DevelopmentYear: 1, IncValue: 100
Product: A, OriginYear: 2018, DevelopmentYear: 2, IncValue: 250
Product: B, OriginYear: 2019, DevelopmentYear: 1, IncValue: 350
Product: B, OriginYear: 2019, DevelopmentYear: 2, IncValue: 400
If this is not what you needed then I would probably suggest sharing some sample data.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论