英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论