NoviceToDotNet
NoviceToDotNet

Reputation: 10815

Sequence contains more than one matching element

When I am trying to set IsDefault property of each dressing items where match a condition it throws an error saying:

Sequence contains more than one matching sequence.

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

Upvotes: 9

Views: 77779

Answers (6)

default
default

Reputation: 11635

Since you are looking for a one liner, you could create your own method doing that.

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);
    }
}

and then call it by

DoActionForEachElement(
               DressingItems,
               xx => xx.DressingInfo.CatID == catId && xx.ProductID == ProductID,
               x => x.IsDefault = false);

This way you don't have to cast the result from Where to a List first.

Upvotes: 1

Yannick Motton
Yannick Motton

Reputation: 36031

The point of the Single operator is to assert that a given sequence only has one item. For instance when retrieving a specific instance by primary key.

I suppose you want to mutate the state of any DressingItem matching the criteria, in which case you have some options, all involving enumerating the resultset, and executing some behavior.

There is no LINQ operator to specifically do this, since LINQ operators are meant to be pure. Pure functions are functions that do not have side effects, and this is exactly what you are trying to do.

There is, however, an extensionmethod on List<T> which does allow this. e.g.

this.DressingItems.Where(di => di.DressingInfo.CatID == catId
                            && di.ProductID == this.ProductID)
                  .ToList()
                  .ForEach(di => 
                  {
                      di.IsDefault = false
                  });

Or you could roll your own:

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;
    }
}

You might ask why the guys at Microsoft decided against adding this to the BCL: As I recall, the idea was that an extensionmethod vs. a foreach() { } construct would not yield much benefits in terms of typing anyway, and it wouldn't help at all in terms of ambiguity. All other operators are side-effect free, and this one is explicitely designed to induce them.

Upvotes: 2

Damith
Damith

Reputation: 63105

this.DressingItems.Where(x=> x.DressingInfo.CatID == catId && 
                                x.ProductID == this.ProductID).ToList()
                 .ForEach(item=>item.IsDefault = false);

Upvotes: 8

Matten
Matten

Reputation: 17603

Well, this exception says that at least two items of the sequence DressingItems match your Where condition. The call to Single then causes the exception because it asserts that only one item is passed in.

Reading your question makes me think that you want to do something on each item of the input sequence, so you will probably use a foreach loop:

foreach(var item in this.DressingItems.Where(xx => xx.DressingInfo.CatID == catId && xx.ProductID == this.ProductID))
{
    item.IsDefault = false;
}

Upvotes: 15

Rex
Rex

Reputation: 2140

you have more than one item in this.DressingItems that match the given CatId and Product Id.

if you are sure there must be one (single), then you have to review how is this.DressingItems loaded.

if it's expected there are more than one, then you have to use foreach to set the values.

Upvotes: 1

Rohit
Rohit

Reputation: 10286

It is an InvalidOperationException thrown by the Single method.

The method is supposed to return only one element, please check the criteria that you use on your query.

However an exception is also thrown when it fails to find any element

Upvotes: 1

Related Questions