我有一个Guid
列表,我在其中保留了项目列表中的任何重复Guid
:
IEnumerable<Guid> duplicateExists = ListOfMyItems
.GroupBy(x => x.ID)
.Where(group => group.Count() > 1)
.Select(group => group.Key);
现在我想检查是否存在重复项,如果是,请从ListOfMyItems
中删除最后一次出现。 DeleteItemFromOrder
只是从数据库中删除一行。
这有效:
foreach (var item in duplicateExists)
{
_ = ListOfMyItems.Remove(ListOfMyItems.Last(x => x.ID == item));
MyLogic.DeleteItemFromOrder(Bill.ID, item);
return;
}
虽然这将进入条件if
,然后在DeleteItemFromOrder
失败,但告诉我duplicateExists - sequence contains no elements
:
if(duplicateExists.Any())
{
_ = ListOfMyItems.Remove(ListOfMyItems.Last(x => x.ID == duplicateExists.First()));
MyLogic.DeleteItemFromOrder(Bill.ID, duplicateExists.First());
return;
}
为什么第二个示例失败?
这是 Linq延迟执行的结果:当你把
IEnumerable<Guid> duplicateExists = ListOfMyItems
.GroupBy(x => x.ID)
.Where(group => group.Count() > 1)
.Select(group => group.Key);
系统实际上不执行查询;然后你有
if (duplicateExists.Any())
{
_ = ListOfMyItems.Remove(ListOfMyItems.Last(x => x.ID == duplicateExists.First()));
MyLogic.DeleteItemFromOrder(Bill.ID, duplicateExists.First());
return;
}
系统执行以下操作:
- 执行
duplicateExists.Any()
并获取true
,因为存在重复项 - 执行
duplicateExists.First()
获取副本并将其从ListOfMyItems
中删除 -ListOfMyItems.Remove
- 尝试再次执行
duplicateExists.First()
MyLogic.DeleteItemFromOrder
,现在失败,因为ListOfMyItems
已被修改并且没有重复项 -duplicateExists
为空
快速补丁:具体化duplicateExists
,强制系统执行查询并将结果存储在集合中,例如数组:
IEnumerable<Guid> duplicateExists = ListOfMyItems
.GroupBy(x => x.ID)
.Where(group => group.Count() > 1)
.Select(group => group.Key)
.ToArray();
LINQ 使用惰性求值。在使用物理列表修改原始数据集之前,您需要将初始查询解析为物理列表,如下所示:
var duplicateExists = ListOfMyItems
.GroupBy(x => x.ID)
.Where(group => group.Count() > 1)
.Select(group => group.Key)
.ToArray();