.net – LINQ Single vs First
If youre expecting a Single record, its always good to be explicit in your code.
I know others have written why you use one or the other, but I thought Id illustrate why you should NOT use one, when you mean the other.
Note: In my code, I will typically use
SingleOrDefault() but thats a different question.
Take, for example, a table that stores
Customers in different languages using a Composite Key (
DBContext db = new DBContext(); Customer customer = db.Customers.Where( c=> c.ID == 5 ).First();
This code above introduces a possible logic error ( difficult to trace ). It will return more than one record ( assuming you have the customer record in multiple languages ) but it will always return only the first one… which may work sometimes… but not others. Its unpredictable.
Since your intent is to return a Single
The following would throw an exception ( which is what you want in this case ):
DBContext db = new DBContext(); Customer customer = db.Customers.Where( c=> c.ID == 5 ).Single();
Then, you simply hit yourself on the forehead and say to yourself… OOPS! I forgot the language field! Following is the correct version:
DBContext db = new DBContext(); Customer customer = db.Customers.Where( c=> c.ID == 5 && c.Lang == en ).Single();
First() is useful in the following scenario:
DBContext db = new DBContext(); NewsItem newsitem = db.NewsItems.OrderByDescending( n => n.AddedDate ).First();
It will return ONE object, and since youre using sorting, it will be the most recent record that is returned.
Single() when you feel it should explicitly always return 1 record will help you avoid logic errors.
Single will throw an exception if it finds more than one record matching the criteria.
First will always select the first record from the list. If the query returns just 1 record, you can go with
Both will throw an
InvalidOperationException exception if the collection is empty.
Alternatively you can use
SingleOrDefault(). This wont throw an exception if the list is empty
.net – LINQ Single vs First
Returns a single specific element of a query
When Use: If exactly 1 element is expected; not 0 or more than 1. If the list is empty or has more than one element, it will throw an Exception Sequence contains more than one element
Returns a single specific element of a query, or a default value if no result found
When Use: When 0 or 1 elements are expected. It will throw an exception if the list has 2 or more items.
Returns the first element of a query with multiple results.
When Use: When 1 or more elements are expected and you want only the first. It will throw an exception if the list contains no elements.
Returns the first element of a list with any amount of elements, or a default value if the list is empty.
When Use: When multiple elements are expected and you want only the first. Or the list is empty and you want a default value for the specified type, the same as
default(MyObjectType). For example: if the list type is
list<int>it will return the first number from the list or 0 if the list is empty. If it is
list<string>, it will return the first string from the list or null if the list is empty.