Friday 27 October 2017

LINQ Single vs SingleOrDefault vs First vs FirstOrDefault

Many people get confused about the difference between SingleSingleOrDefaultFirst, and FirstOrDefaultmethods in Linq. Below is a chart explaining the difference between them and examples of each scenario.
 Single()SingleOrDefault()First()FirstOrDefault()
DescriptionReturns a single, specific element of a sequenceReturns a single, specific element of a sequence, or a default value if that element is not foundReturns the first element of a sequenceReturns the first element of a sequence, or a default value if no element is found
Exception thrown whenThere are 0 or more than 1 elements in the resultThere is more than one element in the resultThere are no elements in the resultOnly if the source is null (they all do this)
When to useIf exactly 1 element is expected; not 0 or more than 1When 0 or 1 elements are expectedWhen more than 1 element is expected and you want only the firstWhen 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
EmployeeidLastnameFirstnameBirthdate
1DavolioNancy12/8/1948 12:00:00 AM
2FullerAndrew2/19/1952 12:00:00 AM
3LeverlingJanet8/30/1963 12:00:00 AM
4PeacockMargaret9/19/1937 12:00:00 AM
5BuchananRobert3/4/1955 12:00:00 AM
6SuyamaMichael7/2/1963 12:00:00 AM
7KingRobert5/29/1960 12:00:00 AM
8CallahanLaura1/9/1958 12:00:00 AM
9DodsworthAnne1/27/1966 12:00:00 AM

Single()

Statement
Employee.Single(e => e.Employeeid == 1)
Expected ResultThere is only one record where Employeeid == 1. Should return this record.
Actual Result
Employeeid1
LastnameDavolio
FirstnameNancy
Birthdate12/8/1948 12:00:00 AM
Statement
Employee.Single(e => e.Firstname == "Robert")
Expected ResultThere are multiple records where Firstname == Robert. Should fail.
Actual ResultInvalidOperationException: Sequence contains more than one element
Statement
Employee.Single(e => e.Employeeid == 10)
Expected ResultThere is no record with Employeeid == 10. Should fail.
Actual ResultInvalidOperationException: Sequence contains no elements

SingleOrDefault()

Statement
Employee.SingleOrDefault(e => e.Employeeid == 1)
Expected ResultThere is only one record where Employeeid == 1. Should return this record.
Actual Result
Employeeid1
LastnameDavolio
FirstnameNancy
Birthdate12/8/1948 12:00:00 AM
Statement
Employee.SingleOrDefault(e => e.Firstname == "Robert")
Expected ResultThere are multiple records where Firstname == Robert. Should fail.
Actual ResultInvalidOperationException: Sequence contains more than one element
Statement
Employee.SingleOrDefault(e => e.Employeeid == 10)
Expected ResultThere is no record with Employeeid = 10. Should return default value.
Actual Resultnull

First()

Statement
Employee.OrderBy(e => e. Birthdate)
.First(e => e.Firstname == "Robert")
Expected ResultThere are multiple records where Firstname == Robert. Should return the oldest one.
Actual Result
Employeeid5
LastnameBuchanan
FirstnameRobert
Birthdate3/4/1955 12:00:00 AM
Statement
Employee.OrderBy(e => e. Birthdate)
.First(e => e.Employeeid == 10)
Expected ResultThere is no record with Employeeid = 10. Should fail.
Actual ResultInvalidOperationException: Sequence contains no elements

FirstOrDefault()

Statement
Employee.OrderBy(e => e. Birthdate)
.FirstOrDefault(e => e.Firstname == "Robert")
Expected ResultThere are multiple records where Firstname == Robert. Should return the oldest one.
Actual Result
Employeeid5
LastnameBuchanan
FirstnameRobert
Birthdate3/4/1955 12:00:00 AM
Statement
Employee.OrderBy(e => e. Birthdate)
.FirstOrDefault(e => e.Employeeid == 10)
Expected ResultThere is no record with Employeeid = 10. Should return default value.
Actual Resultnull

No comments:

Post a Comment