Sequence包含多个匹配元素

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sequence包含多个匹配元素相关的知识,希望对你有一定的参考价值。

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

序列包含多个匹配序列。

(this.DressingItems
     .Where(xx => xx.DressingInfo.CatID == catId 
                        && xx.ProductID == this.ProductID)
     .Single()).IsDefault = false;
答案
this.DressingItems.Where(x=> x.DressingInfo.CatID == catId && 
                                x.ProductID == this.ProductID).ToList()
                 .ForEach(item=>item.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;
}
另一答案

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() { }结构无论如何都不会在打字方面带来太多好处,而且根本没有帮助在歧义方面。所有其他运算符都是无副作用的,并且这个运算符明确地设计用于诱导它们。

另一答案

它是由InvalidOperationException方法抛出的Single

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

但是,如果找不到任何元素,也会抛出异常

另一答案

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

如果您确定必须有一个(单个),那么您必须检查this.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

以上是关于Sequence包含多个匹配元素的主要内容,如果未能解决你的问题,请参考以下文章

实体框架迁移:序列包含多个匹配元素

POJ2778DNA Sequence(AC自动机)

使用visio 2016 绘制画UML时序图(Sequence Diagram)

当元素有多个 id 时匹配

如何利用jQuery给匹配的元素添加多个类名

[ jquery 文档处理 insertBefore(content) before(content|fn) ] 此方法用于把所有匹配的元素插入到另一个指定的元素元素集合的前面,实现外部插入(代码片段