LINQ Single vs SingleOrDefault vs First vs FirstOrDefault

Many people get confused about the difference between Single, SingleOrDefault, First, and FirstOrDefault methods in Linq. Below is a chart explaining the difference between them and examples of each scenario.

Single() SingleOrDefault() First() FirstOrDefault()
Description Returns a single, specific element of a sequence Returns a single, specific element of a sequence, or a default value if that element is not found Returns the first element of a sequence Returns the first element of a sequence, or a default value if no element is found
Exception thrown when There are 0 or more than 1 elements in the result There is more than one element in the result There are no elements in the result Only if the source is null (they all do this)
When to use If exactly 1 element is expected; not 0 or more than 1 When 0 or 1 elements are expected When more than 1 element is expected and you want only the first When more than 1 element is expected and you want only the first. Also it is ok for the result to be empty

Examples

First we create an Employee table for querying. We will test with three difference scenarios:
  • Employeeid = 1: Only one employee with this ID
  • Firstname = Robert: More than one employee with this name
  • Employeeid = 10: No employee with this ID
Employeeid Lastname Firstname Birthdate
1 Davolio Nancy 12/8/1948 12:00:00 AM
2 Fuller Andrew 2/19/1952 12:00:00 AM
3 Leverling Janet 8/30/1963 12:00:00 AM
4 Peacock Margaret 9/19/1937 12:00:00 AM
5 Buchanan Robert 3/4/1955 12:00:00 AM
6 Suyama Michael 7/2/1963 12:00:00 AM
7 King Robert 5/29/1960 12:00:00 AM
8 Callahan Laura 1/9/1958 12:00:00 AM
9 Dodsworth Anne 1/27/1966 12:00:00 AM
Single()

Statement
Employee.Single(e => e.Employeeid == 1)
Expected Result There is only one record where Employeeid == 1. Should return this record.
Actual Result
Employeeid 1
Lastname Davolio
Firstname Nancy
Birthdate 12/8/1948 12:00:00 AM
Statement
Employee.Single(e => e.Firstname == "Robert")
Expected Result There are multiple records where Firstname == Robert. Should fail.
Actual Result InvalidOperationException: Sequence contains more than one element
Statement
Employee.Single(e => e.Employeeid == 10)
Expected Result There is no record with Employeeid == 10. Should fail.
Actual Result InvalidOperationException: Sequence contains no elements
SingleOrDefault()

Statement
Employee.SingleOrDefault(e => e.Employeeid == 1)
Expected Result There is only one record where Employeeid == 1. Should return this record.
Actual Result
Employeeid 1
Lastname Davolio
Firstname Nancy
Birthdate 12/8/1948 12:00:00 AM
Statement
Employee.SingleOrDefault(e => e.Firstname == "Robert")
Expected Result There are multiple records where Firstname == Robert. Should fail.
Actual Result InvalidOperationException: Sequence contains more than one element
Statement
Employee.SingleOrDefault(e => e.Employeeid == 10)
Expected Result There is no record with Employeeid = 10. Should return default value.
Actual Result null
First()

Statement
Employee.OrderBy(e => e. Birthdate)
.First(e => e.Firstname == "Robert")
Expected Result There are multiple records where Firstname == Robert. Should return the oldest one.
Actual Result
Employeeid 5
Lastname Buchanan
Firstname Robert
Birthdate 3/4/1955 12:00:00 AM
Statement
Employee.OrderBy(e => e. Birthdate)
.First(e => e.Employeeid == 10)
Expected Result There is no record with Employeeid = 10. Should fail.
Actual Result InvalidOperationException: Sequence contains no elements
FirstOrDefault()

Statement
Employee.OrderBy(e => e. Birthdate)
.FirstOrDefault(e => e.Firstname == "Robert")
Expected Result There are multiple records where Firstname == Robert. Should return the oldest one.
Actual Result
Employeeid 5
Lastname Buchanan
Firstname Robert
Birthdate 3/4/1955 12:00:00 AM
Statement
Employee.OrderBy(e => e. Birthdate)
.FirstOrDefault(e => e.Employeeid == 10)
Expected Result There is no record with Employeeid = 10. Should return default value.
Actual Result null

0 Comments