Compare Linq Queries For Single Items
Four LINQ Queries for Returning Single Values
Using LINQ queries, there are several methods for querying a collection of records in a database to return a single result, these are:
[edit: this article is about reference types, value types behave slightly different as is noted by Matt T Heffron in the comments.]
They will each behave slightly different in cases where there are no results or more than 1 result to return.
|Operation||==1 result to return||>1 result to return||==0 results to return|
| First();|| First result of collection|| First result of collection|| InvalidOperationException|
| Single() ;|| First result of collection|| InvalidOperationException|| InvalidOperationException|
| FirstOrDefault();|| First result of collection|| First result of collection || Null|
| SingleOrDefault();|| First result of collection|| InvalidOperationException|| Null|
So if there is a possibility that you could return zero results; you have to either check for an
InvalidOperationException or null values. Personally I don’t like having to deal with exceptions for results; I would rather have to deal with null values. So using the chart I have a choice of
SingleOrDefault. Again I don’t want to have to deal with exceptions if the results are greater that 1; so that leaves me with
What if your query will only return the 1 result, which do you choose?
Looking at the TSQL that is generated; there is only one difference.
FirstOrDefault() will do:-
SingleOrDefault() will do:-
Why is this you ask?
It goes back to throwing exceptions. Doing a TOP(2) is the only way to determine whether there is more than 1 result; if there is it will throw the exception.
If you are returning zero results
|Operation||==0 results to return|
As a side note it would be slightly more expensive to check for zero results by doing a count instead of handling a null value as the database will be doing a sub-query as the
Count() operator generates the following TSQL:
SELECT[GroupBy1].[A1] AS [C1]
FROM ( SELECTCOUNT(1) AS [A1]
FROM [dbo].[MyTable] AS [Extent1]
WHERE 100 = [Extent1].[Id]) AS [GroupBy1]
So it might be better to use
FirstOrDefault() and check for nulls.
The post Compare LINQ Queries For Single Items appeared first on Don't Believe The Type.