当我尝试设置符合条件的每个修整项目的IsDefault
属性时,它会抛出错误说:
序列包含多个匹配序列。
(this.DressingItems
.Where(xx => xx.DressingInfo.CatID == catId
&& xx.ProductID == this.ProductID)
.Single()).IsDefault = false;
答案 0 :(得分:10)
好吧,这个例外表示序列DressingItems
中至少有两项与Where
条件匹配。然后调用Single
会导致异常,因为它断言只传入一个项目。
阅读你的问题让我觉得你想对输入序列的每个项目做一些事情,所以你可能会使用foreach循环:
foreach(var item in this.DressingItems.Where(xx => xx.DressingInfo.CatID == catId && xx.ProductID == this.ProductID))
{
item.IsDefault = false;
}
答案 1 :(得分:6)
this.DressingItems.Where(x=> x.DressingInfo.CatID == catId &&
x.ProductID == this.ProductID).ToList()
.ForEach(item=>item.IsDefault = false);
答案 2 :(得分:2)
Single
运算符的意思是声明给定序列只有一个项目。例如,当按主键检索特定实例时。
我想你想改变符合条件的任何DressingItem
的状态,在这种情况下你有一些选项,都涉及枚举结果集,并执行一些行为。
没有专门执行此操作的LINQ运算符,因为LINQ运算符应该是纯粹的。纯函数是没有副作用的函数,这正是你想要做的。
然而,List<T>
上有一个扩展方法允许这样做。 e.g。
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() { }
结构无论如何都不会产生很多好处,并且在歧义方面它根本没有帮助。所有其他操作符都是无副作用的,并且这个操作符被明确地设计用于诱导它们。
答案 3 :(得分:1)
InvalidOperationException
方法抛出Single
。
该方法应该只返回一个元素,请检查您在查询中使用的条件。
但是,如果找不到任何元素
,也会抛出异常答案 4 :(得分:1)
你在this.DressingItems中有多个与给定CatId和Product Id匹配的项目。
如果您确定必须有一个(单个),那么您必须检查如何加载this.DressingItems。
如果预计有多个,那么你必须使用foreach来设置值。
答案 5 :(得分:1)
由于您正在寻找一个班轮,您可以创建自己的方法。
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
。