Sequence contains more than one element - SingleOrDefault not helping

StackTrace picture StackTrace · Mar 27, 2014 · Viewed 59.7k times · Source

I have the line below but still get an exception "Sequence contains more than one element"

Details rd = this.db.Details.SingleOrDefault(x => x.TId == Id && x.TypeId == TypeId);

I was hoping that SingleOrDefault would avoid the exception.

Answer

Kevin picture Kevin · Mar 27, 2014

SingleOrDefault returns a SINGLE element or null if no element is found. If 2 elements are found in your Enumerable then it throws the exception you are seeing. Just like Highlander... with Single - there can be only one.

FirstOrDefault returns the FIRST element it finds or null if no element is found. so if there are 2 elements that match your predicate the second one is ignored.

Assuming you don't care if there are multiple matches and you only want the first one or null if no match is found... then you probably want the following...

Details rd = this.db.Details
    .FirstOrDefault(x => x.TId == Id && x.TypeId == TypeId);

Note that both of these methods only return one element they only differ in what they do after they find a match. First stops looking at that point and returns what it found, Single keeps checking the rest of the list to make sure there are no more matches. The OrDefault part determines what it returns if no match is found. SingleOrDefault or FirstOrDefault returns null if no value is found but if you just use Single or First then it MUST find one match or it will throw an exception.

EDIT: Good point Steve Since First returns the first element you may need to use an OrderBy in order to make sure the element you want is indeed first. For instance... suppose your object had an UpdateDate property and you wanted the object with the most recent UpdateDate...

Details rd = this.db.Details
    .OrderByDescending(x => x.UpdateDate)
    .FirstOrDefault(x => x.TId == Id && x.TypeId == TypeId);