Entity Framework 4 Single() vs First() vs FirstOrDefault()

.NetLinqEntity FrameworkEntity Framework-4Linq to-Entities

.Net Problem Overview


I'm having a devil of a time finding a comparison of the different ways to query for a single item, and when to use each.

Does anyone have a link that compares all these, or a quick explanation as to why you would use one over the other? Are there still more operators that I am unaware of?

Thank you.

.Net Solutions


Solution 1 - .Net

Here is an overview of the different methods:

  • Find() - when you want to get an item by primary key. This will return null if it can't find an item. It will look in the context before going to the database (as pointed out by Yaron in the comments) which can be an important efficiency factor if you need to get the same entity multiple times while the same context is alive.

  • Single() - when you expect exactly one item to be returned by a query. This will throw an exception if the query does not return exactly one item.

  • SingleOrDefault() - when you expect zero or one items to be returned by a query (i.e. you are not sure if an item with a given key exists). This will throw an exception if the query does not return zero or one items.

  • First() - when you expect one or more items to be returned by a query but you only want to access the first item in your code (ordering could be important in the query here). This will throw an exception if the query does not return at least one item.

  • FirstOrDefault() - when you expect zero or more items to be returned by a query but you only want to access the first item in your code (i.e. you are not sure if an item with a given key exists)

Solution 2 - .Net

I always tend to use FirstOrDefault. If you really want to be picky with performance then you should use FirstOrDefault in EF. Under the covers SingleOrDefault uses top (2) in the query because, it needs to check if there is a second row that matches the criteria and if it does, it throws an exception. Basically in SingleOrDefault you are saying that you want to throw an exception if your query returns more then 1 record.

Solution 3 - .Net

It's really very simple: Single returns a single item and throw an exception if there is either none or more than one item. First will return the first item or throw when there is no item. FirstOrDefault will return the first item or return the default value (which is null in case the given type is a reference type) when there is no item.

This is the behavior the API is supposed to have. Note however that the underlying implementation could have a different behavior. While Entity Framework obeys this, a O/RM like LLBLGen can also return null when calling First which is a very strange thing. This was a very strange (and stubborn) decision by the designer IMO.

Solution 4 - .Net

The four methods each have their place; Though you really only have two different operations.

  • First - Expecting a result set that contains multiple items, give me the first item in that set.
  • Single - Expecting a single result back, give me that item.

The xxxxOrDefault() version just adds on "I don't want to consider an empty result set to be an exceptional circumstance."

Solution 5 - .Net

On the other side, you can divide these methods by the core logic, like this:

  • Method will query database directly: Single(), SingleOrDefault(), First(), FirstOrDefault()
  • Method will perform a search in cache before even issuing the query against the database: Find()

For some performance details, especially in the second case you can look here: https://msdn.microsoft.com/en-us/data/hh949853.aspx?f=255&MSPPError=-2147217396#3

In addition, in the first group you can define complex queries, but with Find() method you can provide only entity key for search.

Solution 6 - .Net

Single() and SingleOrDefault() is usually used on unique identifiers such as IDs, while First() or FirstOrDefault() is usually used for a query that could have multiple result but you want only the "Top 1".

Single() or First() would throw an exception if no result is returned, SingleOrDefault() and FirstOrDefault() catches the exception and returns null or default(ResultDataType).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionasfsadfView Question on Stackoverflow
Solution 1 - .NetSteve WillcockView Answer on Stackoverflow
Solution 2 - .NetzeeshanhiraniView Answer on Stackoverflow
Solution 3 - .NetStevenView Answer on Stackoverflow
Solution 4 - .NetChris ShafferView Answer on Stackoverflow
Solution 5 - .NetKryszalView Answer on Stackoverflow
Solution 6 - .NetMilkTea027View Answer on Stackoverflow