.Net – LINQ – Exception – “Sequence contains no elements”

Background

Playing around a bit with LINQ / Entity Framework and running into exceptions.

Unfortunately the code itself is Vendor Supplied and reasonable big and so I am having to set up little test code snippets to have a playground.

With a playground we can try to see if we will be able to set up the right conditions that will “force” the error.

 

NoDB

To make things easy and self contained, we will not have an actual database.

We’ll just declare a simple class and create a few instance of the class.

Each instantiation will be added into a list.

Data

Athlete Team Position
Svetlana Omelchenko 98
Claire O’Donnell 75
Sven Mortensen 88
Cesar Garcia 65

 

Code

Class – Student



    public class Student  
    {  
	
        public string FirstName { get; set; }  
        public string LastName { get; set; }  
        public int Score { get; set; }  

		
    }  


 

Populate List


static ArrayList arrList = new ArrayList();  

static void populateList()
{
	
				
	arrList.Add
	(  
		new Student  
			{  
				  FirstName = "Svetlana"
				, LastName = "Omelchenko"
				, Score = 98  
			}
	);  
	
	arrList.Add
	(  
		new Student  
			{  
				  FirstName = "Claire"
				, LastName = "O’Donnell"
				, Score = 75
			}
	);  
	
	arrList.Add
	(  
		new Student  
			{  
				  FirstName = "Sven"
				, LastName = "Mortensen"
				, Score = 88
			}
	);  
	
	arrList.Add
	(  
		new Student  
			{  
				  FirstName = "Cesar"
				, LastName = "Garcia"
				, Score = 65
			}
	);  
	
}

 

Get Minimum Score to display


Console.Write("Please enter minimum score :- ");

String value = Console.ReadLine();

int iScore = -1;


try 
{
	
	iScore  = Int32.Parse(value); 
		
	Console.WriteLine("{0} --> {1}", value, iScore);
}
catch (FormatException) 
{
	Console.WriteLine("{0}: Bad Format", value);
}   

catch (OverflowException) 
{
	Console.WriteLine("{0}: Overflow", value);   

}  

 

Query List (arrList) filtering on mininal score


var query = from Student student in arrList  
	    orderby student.Score descending
            where student.Score > iScore
            select student
						;  

Simple Result Set Iteration


						
foreach (Student s in query) 
{			
   Console.WriteLine(s.LastName + ": " + s.Score);  
};  

Access Recordset


/*
	Get First Element in recordset
*/
try
{

	//get First element in set
	var varElement = query.First();

	if (varElement != null)
	{
		Console.Write("Lastname is :- " );
		Console.WriteLine(varElement.LastName);
	}

}
catch (Exception ex)
{

	Console.WriteLine("Error getting first element - query.First()");

	Console.WriteLine("Exception Message:- " + ex.Message);

	Console.WriteLine("StackTrace:- " + ex.StackTrace);

	Console.WriteLine(STRING_LINEBREAK);
}


/*
	Get Average Score in recordset
*/
try
{

	fltAverage = query.Average(e => e.Score);

	Console.Write("Average Score " );
	Console.WriteLine(fltAverage);


}
catch (Exception ex)
{

	Console.WriteLine("Error getting average score - query.Average(e => e.Score) ");

	Console.WriteLine("Exception Message:- " + ex.Message);

	Console.WriteLine("StackTrace:- " + ex.StackTrace);
				
	Console.WriteLine(STRING_LINEBREAK);

}					


Exception

  1. Exception Message:-
    • Sequence contains no elements
  2. Exception StackTrace :-
    • at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
    • at System.Linq.Enumerable.Average(IEnumerable`1 source)

Remediation

Plan

Our hope is that we will need a couple of helper methods.
The helper methods will check the recordset of a LINQ Query and compute counts, isEmpty, etc.

Extension Methods

Lasse Espeholt

Code provided by Lasse Espeholt here.

 

static class EnumerableExtensions
{
	public static int Count(this IEnumerable source)
	{
		int res = 0;

		foreach (var item in source)
		{
			res++;
		}
		
		return res;
	}
	
	public static Boolean isEmpty(this IEnumerable source)
	{
		Boolean bEmpty = true;

		foreach (var item in source)
		{
			bEmpty = false;
			break;
		}
		
		return (bEmpty);
	}
	
}

Validate data before Use

 

// Get number of Elements
iNumberofElements = query.Count();

//Is List Empty
bEmpty = query.isEmpty();

// If List is not empty	
if (bEmpty == false)
{
	
	Console.WriteLine("Count :- " + iNumberofElements);	

	//get First element of a Sequence
	var varElement = query.FirstOrDefault();

	//If first element is not null
	if (varElement != null)
	{
	
		Console.WriteLine("Lastname :- " + varElement.LastName);
	
	}	
	
	fltAverage = query.Average(e => e.Score);
	
	Console.WriteLine("Average Score :- " + fltAverage);
	
}	
else
{
	
	Console.Write("Empty recordset returned from searching for test scores greater than :- ");
	
	Console.WriteLine(iScore);
}		
	

 

Summary

There are a few safeguards that one can employ.  Example are listed below:

  1. Sequence.FirstOrDefault
  2. If Sequence.Any the Sequence.First
  3. Sanitize recordset using count or exists before aggregating data

 

References

  1. docs.microsoft.com
    •  Docs/NET / C# Guide / Programming guide / Programming concepts / LINQ
      • How to: Query an ArrayList with LINQ (C#)
        Link
  2. Data Developer Center
    • Performance Considerations for EF 4, 5, and 6
      Link
  3. Technical Overhead
    • Nathan
      • LINQ Single vs SingleOrDefault vs First vs FirstOrDefault
        Link
  4. DotNetPerls
    • FirstOrDefault
      Link
  5. Telerik
    • How to: Convert the Results of a LINQ Query to an Array
      Link
  6. Tech Crazy Zone
    • Gihan Lakmal
      • C# – Fix Sequence Contains no elements
        Link
  7. Stack Overflow
    • Calculating Count for IEnumerable (Non Generic)
      Link
    • Implicitly typed local variables must be initialized
      Link
    • Entity Framework 4 Single() vs First() vs FirstOrDefault()
      Link
    • Sequence contains no elements?
      Link

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s