Today, we're going to fix a LINQ Error: Sequence contains no elements which the programmers encounter in daily life. It usually happens when we're using the Single() or First() method to retrieve a value from a dataset. In this study blog, we'll explore why it happens and how to resolve it.
What is "Sequence contains no elements" #
This error happens we use Single() or First() to retrieve a value but the value doesn't exist in the dataset. Let's look an example:
internal class Student
{
private string name;
private int age;
private string gender;
private string hobby;
public Student(string name, int age, string gender, string hobby)
{
this.name = name;
this.age = age;
this.gender = gender;
this.hobby = hobby;
}
public string Name
{
get { return name; }
set { name = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
public string Gender
{
get { return gender; }
set { gender = value; }
}
public string Hobby
{
get { return hobby; }
set { hobby = value; }
}
}
First, I create a Student class with some properties.
List students = new List()
{
new Student("Alex", 22, "Male", "Basketball"),
new Student("Cindy", 20, "Female", "Badminton"),
new Student("Joshua", 20, "Male", "Swimming"),
new Student("Emily", 21, "Female", "Basketball"),
new Student("Josely", 22, "Female", "Jogging"),
};
var result = students.Where(student => student.Name == "Alex").Single();
Console.WriteLine($"Here is the result:\n {Newtonsoft.Json.JsonConvert.SerializeObject(result)}");
Then, I create a list of Student objects in my program.cs and use the Single() to get the only Student with name Alex.
We need to install Newtonsoft library in the Nuget Package so that we can use it to print out the JSON string of our Student object result.
This is the result:
Here is the result:
{"Name":"Alex","Age":22,"Gender":"Male","Hobby":"Basketball"}
Look, now we didn't get any errow because there's one Student with name Alex. Let's see another example:
List students = new List()
{
new Student("Alex", 22, "Male", "Basketball"),
new Student("Cindy", 20, "Female", "Badminton"),
new Student("Joshua", 20, "Male", "Swimming"),
new Student("Emily", 21, "Female", "Basketball"),
new Student("Josely", 22, "Female", "Jogging"),
};
var result = students.Where(student => student.Name == "Clarence").Single();
Console.WriteLine($"Here is the result:\n {Newtonsoft.Json.JsonConvert.SerializeObject(result)}");
This is the result:
System.InvalidOperationException: 'Sequence contains no elements'
Now, the Sequence contains no elements error occurs. Let's look at another example using First() method:
List students = new List()
{
new Student("Alex", 22, "Male", "Basketball"),
new Student("Cindy", 20, "Female", "Badminton"),
new Student("Joshua", 20, "Male", "Swimming"),
new Student("Emily", 21, "Female", "Basketball"),
new Student("Josely", 22, "Female", "Jogging"),
};
var result = students.Where(student => student.Name == "Clarence").First();
Console.WriteLine($"Here is the result:\n {Newtonsoft.Json.JsonConvert.SerializeObject(result)}");
This is the result:
System.InvalidOperationException: 'Sequence contains no elements'
Same error occurs. Why? we'll see that next.
Causes #
Let's see the different types of errors that will be thrown while using Single() or First() method:
Single():
- ArgumentNullException: Thrown when the source sequence is null.
- InvalidOperationException: Thrown when the no element satisfies the condition OR more than one element satisfies the condition OR the source sequence is empty.
First():
- ArgumentNullException: Thrown when the source sequence is null.
- InvalidOperationException: Thrown when no element satisfies the condition OR the source sequence is empty.
According to the example on previous section, both Single() and First() method are getting the same error, that's System.InvalidOperationException: 'Sequence contains no elements'. This is because both of them can't find a value that meets the condition stated in the statement! So, how can we allow our program to run while this error is catched without being thrown at the output? Let's go to the next section.
Solution #
The solution is pretty simple, that's: instead of Single() or First(), use SingleOrDefault() or FirstOrDefault(). Instead of throwing the error "Sequence contains no elements", they will return a null value if no result found. Let's say:
List students = new List()
{
new Student("Alex", 22, "Male", "Basketball"),
new Student("Cindy", 20, "Female", "Badminton"),
new Student("Joshua", 20, "Male", "Swimming"),
new Student("Emily", 21, "Female", "Basketball"),
new Student("Josely", 22, "Female", "Jogging"),
};
var result = students.Where(student => student.Name == "Clarence").SingleOrDefault();
Console.WriteLine($"Here is the result:\n {Newtonsoft.Json.JsonConvert.SerializeObject(result)}");
This is the result:
Here is the result:
null
and for FirstOrDefault():
List students = new List()
{
new Student("Alex", 22, "Male", "Basketball"),
new Student("Cindy", 20, "Female", "Badminton"),
new Student("Joshua", 20, "Male", "Swimming"),
new Student("Emily", 21, "Female", "Basketball"),
new Student("Josely", 22, "Female", "Jogging"),
};
var result = students.Where(student => student.Name == "Clarence").FirstOrDefault();
Console.WriteLine($"Here is the result:\n {Newtonsoft.Json.JsonConvert.SerializeObject(result)}");
This is the result:
Here is the result:
null
Now, we can run our program without the error: Sequence contains no elements in the output. Although the condition is not met, we still can get a default object, which is null. Looks, the solution is pretty simple right?
You can also execute some codes based on the object returned or return NotFound() if you're using ControllerBase.
For instance:
List students = new List()
{
new Student("Alex", 22, "Male", "Basketball"),
new Student("Cindy", 20, "Female", "Badminton"),
new Student("Joshua", 20, "Male", "Swimming"),
new Student("Emily", 21, "Female", "Basketball"),
new Student("Josely", 22, "Female", "Jogging"),
};
var result = students.Where(student => student.Name == "Clarence").FirstOrDefault();
if(result != null)
{
Console.WriteLine($"Here is the result:\n {Newtonsoft.Json.JsonConvert.SerializeObject(result)}");
}
else
{
Console.WriteLine("The student is not found in the record!");
}
This is the result:
The student is not found in the record!
The Conclusion #
In this study blog, we've learned what is Sequence contains no elements in LINQ, why it happens and how to resolve it. Note that using SingleOrDefault() or FirstOrDefault() is always better as they will not throw exception and terminate the program. Instead, they can help the programmers to check the output while executing the statement. Thank you and enjoy your day! :)