Apr

3

LINQ Single vs SingleOrDefault vs First vs FirstOrDefault

Posted by 31 Comments

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

Category: .NET, Development, Linq, Uncategorized

Comments (31)

Trackback URL | Comments RSS Feed

  1. Troy says:

    Nice chart, very helpful. Thank you.

  2. kanna says:

    will default value is always be null?

    • Nathan says:

      Good question, the answer is no. In my examples, my employee object did not have a default value, therefore null is returned as the default value.

      Take a list of integers for example. The default value for an int is 0. So in this example:

      List i = new List()
      i.FirstOrDefault()

      you would get 0 returned as the default. However, if you were to cast the int as nullable:

      List i = new List()
      i.FirstOrDefault()

      then you would get null as the default value. Hope this helps.

      • saidi says:

        because employee is reference type,by default every reference type default value is null,but in the case of value types like int,double,float default value is 0

  3. Mahesh Nagar says:

    great article …keep it up .

  4. Manoj says:

    Great Article. Request you to keep going with such nice articles.

  5. Aruna says:

    Great Article. very helpful. Thank you.

  6. naveena says:

    Great article… Thanks a lot for the information

  7. Manish says:

    In last example of FirstorDefault,
    Employee.OrderBy(e => e. Birthdate)
    .First(e => e.Employeeid == 10)

    You have written wrong query, it should be
    Employee.OrderBy(e => e. Birthdate)
    .FirstOrDefault(e => e.Employeeid == 10)

    Btw nice explanation!

  8. Mateen says:

    How can I get those repeated records then?

    • Nathan says:

      first[ordefault] and single[ordefault] return only one item each. If you want multiple just use the “Where” method:

      Employee.Where(e => e.Firstname == "Robert")

  9. Sumit Kumar says:

    Nice one…………keep it up

  10. Asif M says:

    Great work…..

  11. If everybody wrote technical articles like you, the world would be a marvelous place. Keep up the good work please!

  12. siva says:

    hi i want to select details from table customer. i was use following linq qurey but it return null.The cistomer_id in customer table.
    here pramproductinfo.BillToCustomerCode=”150304-1″.

    db.customers.Where(c => c.customer_id == pramproductinfo.BillToCustomerCode).SingleOrDefault()

  13. Gaurav Sharma says:

    Very good article thanks for sharing.

  14. Anonymous says:

    Good one

  15. Anonymous says:

    Pretty Nice.

  16. kamal says:

    Very Nice chart.

  17. Yaseen says:

    Very Nice artical and easily understand every one.

  18. gopiraj says:

    Great….I had never came across this type of Explanation…Its very clear and helpful….please update some more technical stufff…..thank you

  19. Tejeswara Rao M says:

    Nice article. Thanks.

  20. JagaM says:

    Very clear explanation. Request you to keep sharing more. Thanks alot.

  21. Best Explanation for LINQ Single vs SingleOrDefault vs First vs FirstOrDefault

    I understood the whole point as soon as I saw the chart. Cheers (Y)

  22. Heiko says:

    Good and easy explanation.

    But… just as a hint:
    The examples with looking for a match with employeeid in the employee table should be rewritten!
    Looking for an entry in a table by its primary key should be done with .Find
    *(like employeeid on employee table is supposed to be)
    Plus: putting an OrderBy in front of a primarykey query makes no sense at all (as there will be never more than 1 match).
    I’m sure you can find better examples :)

    • Nathan says:

      Great points. For the OrderBy I was trying to help visual the result set to help users understand what they should expect to see; though you are absolutely right that it doesn’t make any sense to use it in front of a primary key.

      Also remember that .Find() will only work on Lists.

Leave a Reply