LINQ: Understand the difference between Single vs SingleOrDefault vs First vs FirstOrDefault extension methods
Single(),
SingleOrDefault(), First() and FirstOrDefault() are extension methods of the
Enumerable class.
“These Extension
methods are static method that we can call from an instance object which
implement IEnumerable interface.”
Many
people get confused about the difference between Single, SingleOrDefault,
First, and FirstOrDefault extension methods in LINQ.
Let’s
understand the difference between all these methods:
Single(): This method
searches for single instances in a collection which matching a condition. If
the collection has 0 or more than one matching element, we get an exception.
This
method should be used if you are sure that there will exactly 1 element, for
example you can use Single with primary column of an object.
SingleOrDefault(): This method returns
a single, specific element in a collection, or a default value if that element
is not found. If there is no matching element found then by default it’ll
return null value.
However
this method will throw exception if there is more than one matching element in
the collection.
This
method should be used if 0 or 1 matching elements are expected.
First():
This
method locates the first matching element in a collection. If the collection
has no matching element, we get an exception.
This
method should be used when more than one element is expected and you want only
the first.
FirstOrDefault():
This
method is almost the same as First. The difference is how it handles empty
collections. If a collection is empty, it returns the default value for the
type. This method eliminates the exceptions.
This
method should be used when more than one element is expected and you want only
the first element and with that this method provides you assurance that there
will be no exception if there is no matching element found.
So
I hope you got the fair idea about these methods, still need more clarification?
Don’t worry; See
below example for more understanding:
Example:
First
we’ll create an object of employee.
public class
Employee
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
}
|
Then
we’ll write a method to return list of employees (for example we are using
hard-coded data, in real scenario data will be populated from DB).
/// <summary>
/// Method return list
of employees
/// </summary>
/// <returns></returns>
private List<Employee> GetEmployees()
{
var
employeeList = new List<Employee>();
for (var i = 1; i <= 5; i++)
{
employeeList.Add(new Employee
{
Id = i,
Name = "Name" + i,
});
}
return
employeeList;
}
|
Id
= 1, i.e. only one employee exist against this Id
City
= Gurgaon, i.e. more than one employee for this city
Id
= 100: No employee exists against this Id
Populate
all employees in a list as:
var employeeList = GetEmployees();
|
Method:
Single()
|
Statement 1: employeeList.Single(e => e.Id
== 1);
Result: Employee
object returned having Id as 1. This method is best is this scenario.
Statement2: employeeList.Single(e =>
e.City == "Gurgaon");
Result: There are
more than one matching element, it’ll throw exception: InvalidOperationException:
Sequence contains more than one element
Statement3: employeeList.Single(e => e.Id
== 100);
Result: There is
no matching employee with Id 100, it’ll throw exception: InvalidOperationException:
Sequence contains no elements
|
Method:
SingleOrDefault()
|
Statement 1: employeeList.SingleOrDefault(e
=> e.Id == 1);
Result: Employee
object returned having Id as 1.
Statement2: employeeList.SingleOrDefault(e
=> e.City == "Gurgaon");
Result: There are
more than one matching element, it’ll throw exception: InvalidOperationException:
Sequence contains more than one element
Statement3: employeeList.SingleOrDefault(e
=> e.Id == 100);
Result: There is
no matching employee with Id 100; it’ll return default null value.
|
Method:
First()
|
Statement 1: employeeList.First(e => e.Id
== 1);
Result: Employee
object returned having Id as 1.
Statement2: employeeList.First(e =>
e.City == "Gurgaon");
Result: There are
more than one matching element, it’ll return first employee object from list.
Statement3: employeeList.First(e => e.Id
== 100);
Result: There is
no matching employee with Id 100; it’ll throw exception InvalidOperationException:
Sequence contains no elements.
|
Method:
FirstOrDefault()
|
Statement 1: employeeList.FirstOrDefault(e => e.Id == 1);
Result: Employee
object returned having Id as 1.
Statement2: employeeList.FirstOrDefault(e => e.City == "Gurgaon");
Result: There are
more than one matching element, it’ll return first employee object from list.
Statement3: employeeList.FirstOrDefault(e => e.Id == 100);
Result: There is
no matching employee with Id 100; it’ll return default null value. This
method is good in the case you are not sure whether matching element exist or
not.
|
Hope
that clears all the confusions, your comment or suggestions will be highly appreciated.
Comments
Post a Comment