使用 Linq 修剪掉重复项
本文关键字:Linq 修剪 使用 | 更新日期: 2023-09-27 18:34:22
我正在使用一个返回重复 ID 的 API。我需要使用 EF 将这些值插入到我的数据库中。在尝试添加对象之前,我想修剪掉任何重复项。
我有一个我正在尝试编写的代码的小示例。
var itemsToImport = new List<Item>(){};
itemsToImport.Add(new Item() { Description = "D-0", Id = 0 });
for (int i = 0; i < 5; i++)
{
itemsToImport.Add(new Item(){Id = i,Description = "D-"+i.ToString()});
}
var currentItems = new List<Item>
{
new Item() {Id = 1,Description = "D-1"},
new Item(){Id = 3,Description = "D-3"}
};
//returns the correct missing Ids
var missing = itemsToImport.Select(s => s.Id).Except(currentItems.Select(s => s.Id));
//toAdd contains the duplicate record.
var toAdd = itemsToImport.Where(x => missing.Contains(x.Id));
foreach (var item in toAdd)
{
Console.WriteLine(item.Description);
}
我需要更改什么才能修复我的变量"toAdd",即使有重复也只返回一条记录?
您可以通过按 Id 分组,然后选择每个组中的第一项来执行此操作。
var toAdd = itemsToImport
.Where(x => missing.Contains(x.Id));
成为
var toAdd = itemsToImport
.Where(x => missing.Contains(x.Id))
.GroupBy(item => item.Id)
.Select(grp => grp.First());
使用 MoreLINQ 中的 DistinctBy,正如 Jon Skeet 在 https://stackoverflow.com/a/2298230/385844 年推荐的那样
调用将如下所示:
var toAdd = itemsToImport.Where(x => missing.Contains(x.Id)).DistinctBy(x => x.Id);
如果你出于某种原因不想(或不能)使用MoreLINQ,DistinctBy 很容易实现:
static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> projection)
{
var set = new HashSet<TKey>();
foreach (var item in sequence)
if (set.Add(projection(item)))
yield return item;
}
您可以使用
Distinct
函数。不过,您需要覆盖Equals
和GetHashCode
Item
(假设它们包含相同的数据)。
或者使用 FirstOrDefault
取回具有匹配 ID 的第一个项目。
itemsToImport.Where(x => missing.Contains(x.Id)).FirstOrDefault()