6

当我试图设置IsDefault匹配条件的每个敷料项目的属性时,它会抛出一个错误说:

序列包含多个匹配序列。

(this.DressingItems
     .Where(xx => xx.DressingInfo.CatID == catId 
                        && xx.ProductID == this.ProductID)
     .Single()).IsDefault = false;
4

6 回答 6

12

好吧,这个例外表明序列中至少有两个项目DressingItems符合您的Where条件。调用Singlethen 会导致异常,因为它断言只有一项传入。

阅读你的问题让我觉得你想对输入序列的每个项目做一些事情,所以你可能会使用一个 foreach 循环:

foreach(var item in this.DressingItems.Where(xx => xx.DressingInfo.CatID == catId && xx.ProductID == this.ProductID))
{
    item.IsDefault = false;
}
于 2013-08-13T07:08:28.633 回答
8
this.DressingItems.Where(x=> x.DressingInfo.CatID == catId && 
                                x.ProductID == this.ProductID).ToList()
                 .ForEach(item=>item.IsDefault = false);
于 2013-08-13T07:11:20.867 回答
2

运算符的要点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() { }构造在打字方面无论如何都不会产生太多好处,而且它根本无助于歧义的条款。所有其他运算符都是无副作用的,而这个运算符是专门为诱导它们而设计的。

于 2013-08-13T07:28:04.573 回答
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第一个。

于 2013-08-13T07:31:14.893 回答
1

它是InvalidOperationException由方法抛出的Single

该方法应该只返回一个元素,请检查您在查询中使用的条件。

但是,当找不到任何元素时也会引发异常

于 2013-08-13T07:07:36.313 回答
1

您在 this.DressingItems 中有多个项目与给定的 CatId 和 Product Id 匹配。

如果您确定必须有一个(单个),那么您必须查看 this.DressingItems 是如何加载的。

如果预计有多个,那么您必须使用 foreach 来设置值。

于 2013-08-13T07:07:51.147 回答