• Anthony Stevens

The Linq FirstOrDefault() Method and Null Resultsets

Software

I was doing some Linq programming and kept hitting the problem where if there were no results to a query, but I wanted to call First() or Single() to get a single row, I kept getting “Sequence contains no elements” exceptions.

There didn’t seem to be an easy way to tell if the resultset was null, because it wasn’t really NULL, not in a C# sense. And trying to get Count() would throw a separate exception if there really was at least one element, because I couldn’t enumerate a sequence more than once.

Luckily an offhand comment by Scott Guthrie on his blog helped me out a lot. Use FirstOrDefault() with a dummy criteria as an argument:

var record = <blah>.GetResult().FirstOrDefault(p => p.id <0)

If there are no results, this code will return NULL to the variable, which you can then easily check in your code.

Thanks Scott!

10 Comments

10 Comments

  1. minhtuan  •  May 9, 2008 @6:12 pm

    thanks so much!

  2. Michael Hanney  •  Jun 12, 2008 @3:06 pm

    Nice. This is exactly what I was looking for. Thanks for posting.

  3. JDS  •  Oct 2, 2008 @2:27 am

    There is an overload for FirstOrDefault that takes no parameters!

  4. Brad Sickles  •  Sep 10, 2009 @10:03 am

    Wouldn’t it make more sense to avoid object instantiation doing this instead?

    int count = .GetResult().Count(p => p.id < 0)

  5. anthonyrstevens  •  Sep 10, 2009 @6:56 pm

    Brad: yeah, if all I was trying to do was get the count. In reality I would like to get the first element of the resultset.

  6. Lanker  •  Oct 5, 2009 @9:35 pm

    Very nice. Thanks alot!

  7. Michael Petty  •  Mar 10, 2010 @12:50 pm

    In order to have a Linq expression return a null value whenever a row is not found in the database or list, we can cast the return value to a nullable type in the Select expression. Here’s an example:

    int productID = 21; // This is a non-existant product ID.
    decimal? price = null; // Initialize the price to a null value.
    price = oc.Products.Where(p => p.ID == productID)
    .Select(p => (decimal?)p.Price)
    .FirstOrDefault();
    // p.Price is defined as Decimal which would return 0 as the default value.
    // The method FirstOrDefault would return a 0 if we didn’t
    // cast p.Price to a “decimal?”

    if (!price.HasValue)
    {
    // A product matching productID was not found.
    }
    else
    {
    // A product matching productID was found.
    }

  8. Trish Rempel  •  Apr 21, 2010 @6:52 am

    Thanks Michael – I had the same linq issue, trying to assign the result to a DateTime? variable.

  9. Adam Tuliper  •  May 7, 2010 @9:24 am

    Just to append to this info – the default value for an object type we define which is what Im assuming is, will be null. So calling .FirstOrDefault() will return null if there are no elements. If it happens to be a list of integers then the default should be 0 in that case, in our custom objects though they will generally be null, no need for a dummy argument. Scott Gu’s example was simply to replace the Single(some criteria). If you dont have the criteria you are searching for then no ‘dummy argument’ is required

  10. stray  •  Apr 23, 2011 @2:16 pm

    thank you!