序列包含多个匹配元素
本文关键字:元素 包含多 | 更新日期: 2023-09-27 18:27:30
当我试图设置与条件匹配的每个敷料项目的IsDefault
属性时,它会抛出一个错误:
序列包含多个匹配序列。
(this.DressingItems
.Where(xx => xx.DressingInfo.CatID == catId
&& xx.ProductID == this.ProductID)
.Single()).IsDefault = false;
这个异常表示序列DressingItems
中至少有两个项符合Where
条件。对Single
的调用会导致异常,因为它断言只传入了一个项
阅读你的问题会让我觉得你想对输入序列的每一项做点什么,所以你可能会使用foreach循环:
foreach(var item in this.DressingItems.Where(xx => xx.DressingInfo.CatID == catId && xx.ProductID == this.ProductID))
{
item.IsDefault = false;
}
this.DressingItems.Where(x=> x.DressingInfo.CatID == catId &&
x.ProductID == this.ProductID).ToList()
.ForEach(item=>item.IsDefault = false);
Single
运算符的作用是断言给定序列只有一个项。例如,当通过主键检索特定实例时。
我想你想改变任何符合条件的DressingItem
的状态,在这种情况下,你有一些选项,所有这些都涉及枚举结果集和执行一些行为。
由于LINQ操作符是纯的,因此没有LINQ操作符专门做这件事。纯函数是没有副作用的函数,这正是你想要做的
然而,List<T>
上有一个扩展方法允许这样做。例如
this.DressingItems.Where(di => di.DressingInfo.CatID == catId
&& di.ProductID == this.ProductID)
.ToList()
.ForEach(di =>
{
di.IsDefault = false
});
或者你可以推出自己的:
public static class EnumerableExtensions
{
public static IEnumerable<T> ForEach<T>(
this IEnumerable<T> source,
Action<T> mutator)
{
var buffered = source.ToList();
buffered.ForEach(mutator);
return buffered;
}
}
你可能会问,为什么微软的人决定不把它添加到BCL中:据我回忆,当时的想法是,扩展方法与foreach() { }
构造在打字方面不会产生太多好处,而且在歧义方面也没有任何帮助。所有其他操作符都是无副作用的,而这一个操作符是明确设计用来诱导它们的。
它是由Single
方法抛出的InvalidOperationException
。
该方法应该只返回一个元素,请检查您在查询中使用的条件。
然而,当它未能找到任何元素
您有多个项目。与给定类别Id和产品Id匹配的DressingItems。
如果你确定一定有一个(单身),那么你必须回顾一下这是怎么回事。DressingItems已加载。
如果期望有多个值,那么必须使用foreach来设置值。
由于您正在寻找一个单行,您可以创建自己的方法来实现这一点。
public static void DoActionForEachElement<T>(IEnumerable<T> items, Func<T, bool> predicate, Action<T> action)
{
foreach (var item in items)
{
if (predicate(item))
action(item);
}
}
然后通过调用
DoActionForEachElement(
DressingItems,
xx => xx.DressingInfo.CatID == catId && xx.ProductID == ProductID,
x => x.IsDefault = false);
这样就不必先将结果从Where
强制转换为List
。