20

While execution of following linq, I get this exception:

" Sequence contains no elements"

Linq code:

   newGradeRow[rowCnt + 1 + "Grade " + ExamName] = 
      objDataSet.Tables[1].Rows.Cast<DataRow>()
      .Where(p => Convert.ToDecimal(p["EMG_MARKS_ABOVE"]) <= extSubMarks  
         && extSubMarks <= Convert.ToDecimal(p["EMG_MARKS_BELOW"]))
      .Select(p => Convert.ToString(p["EMG_GRADE_NAME"]))
      .First();

Can any one help me on this?

Community
  • 1
  • 1
Sumith Amin
  • 257
  • 1
  • 2
  • 5
  • 3
    The exception is clear - one of the lists you are working with is empty and is not returning any results. – Oded Nov 27 '11 at 12:49
  • 2
    as i mentioned in the question while execution i get an exception as "Sequence contains no elements". can you please tell me why i am getting that exception or what is wrong in the code. i am new to .net. – Sumith Amin Nov 27 '11 at 12:50
  • 2
    I think your collection has no items. What do *you* think you should do? This question is an exercise in basic thought. –  Nov 27 '11 at 13:00
  • 12
    Not sure why this was closed, it's a pretty basic question but would serve as a good way to answer this simple question for future linq newbies – Ben Robinson Nov 27 '11 at 17:15
  • 3
    This shouldn't have been closed. I'm faced with this same exception, and I can't find any answers anywhere else. Oh well. I'll just ask again. :-) – Arrow Aug 03 '12 at 19:05
  • This question was closed for wrong reason. It's straightforward, known what's being asked e has an correct answer with some upvotes (that shows that other people had same doubt and found answer helpful). Perhaps, it should be closed by duplicate.. http://stackoverflow.com/questions/1324199, http://stackoverflow.com/questions/942545, http://stackoverflow.com/questions/18115926... – Andre Figueiredo Jan 02 '14 at 19:48

5 Answers5

51

The exception is thrown in the First method call if the sequence is empty as it is stated in the documentation. In this case it is better to use the FirstOrDefault method - it will return the default value (in specific case null) and no exception will be thrown.

danyloid
  • 1,677
  • 3
  • 21
  • 47
7

Start by breaking it up. Your current code offers no grip for a debugger.

var r1 = objDataSet.Tables[1].Rows;
var r2 = r1.Cast<DataRow>();
System.Diagnostics.Debug.Print("r2: {0}", r2.Count());
var r3 = r2.Where(p => Convert.ToDecimal(p["EMG_MARKS_ABOVE"]) <= extSubMarks  
            && extSubMarks <= Convert.ToDecimal(p["EMG_MARKS_BELOW"]));
System.Diagnostics.Debug.Print("r3: {0}", r3.Count());
var r4 = r3.Select(p => Convert.ToString(p["EMG_GRADE_NAME"]));
var r5 = r4.First();

newGradeRow[rowCnt + 1 + "Grade " + ExamName] = r5;
H H
  • 263,252
  • 30
  • 330
  • 514
  • Whilst the code is a bit fiddly, it is pretty clear that the ONLY thing there that would throw that exception is the call to First() which requires 1 or more elements. – Ben Robinson Nov 27 '11 at 13:26
  • @BenRobinson, Agreed, but is it empty before or after the `Where()` ? I would want to know. – H H Nov 27 '11 at 13:28
  • 3
    Fair enough, but I would suggest you mention that it is the call to `First()` that throws and explain the difference between `First()` and `FirstOrDefault()` – Ben Robinson Nov 27 '11 at 13:31
  • I think Henk's point is to break up the code for debugging purposes. Lines 1 and 2 could also throw exceptions. – MJ Hufford Nov 27 '11 at 16:44
3

It's difficult to say WHICH sequence has no elements when you have so many strung together in the same line of code. Try breaking your code down to multiple lines and then debug it. This will make it more readable as well.

var myVariable = objDataSet.Tables[1]; 
var myEntity = myVariable.Rows.Cast<DataRow>().Where(
  p => Convert.ToDecimal(p["EMG_MARKS_ABOVE"]) <= extSubMarks
  && extSubMarks <= Convert.ToDecimal(p["EMG_MARKS_BELOW"]))
  .Select(p => Convert.ToString(p["EMG_GRADE_NAME"])).FirstOrDefault();

If the problem is somewhere in your Lambda expression, you may want to break it out into a foreach loop (just for the sake of debugging & having access to the data within the immediate window of VS).

MJ Hufford
  • 636
  • 4
  • 11
  • 2
    ThYou have changed the last call to `FirstOrDefault()` which will get rid of the exception but you haven't mentioned that which is a bit odd. – Ben Robinson Nov 27 '11 at 13:28
  • My mistake. I prefer using the FirstOrDefault() extension method over First() for better exception handling. You can then check for nulls afterward before proceeding. – MJ Hufford Nov 27 '11 at 16:43
1

You should take care about this that: What Linq Expression/ query does not contain any record then you can not use Single() and First().

On the place Single() in your Lambda expression use FirstOrDefault()

Vahid Farahmandian
  • 6,081
  • 7
  • 42
  • 62
Niranjan Singh
  • 18,017
  • 2
  • 42
  • 75
0

objDataSet.Tables[1] is empty?

Perhaps the data is in objDataSet.Tables[0] ?

Either way, you can test with objDataSet.Tables.Count() > 0

You can do the same for Rows: objDataSet.Tables[1].Rows.Count() > 0

Tshilidzi Mudau
  • 7,373
  • 6
  • 36
  • 49
Neil Thompson
  • 6,356
  • 2
  • 30
  • 53