0

I am having issues with a Linq query when it runs I receive the error Object reference not set to an instance of an object.

var RestaurantName = (from r in objCtx.Restaurants
                      where r.id == item.restaurantid
                      select r).SingleOrDefault<Restaurant>().Name;

I then changed the query to

var RestaurantName = (from r in objCtx.Restaurants
                      where r.id == item.restaurantid
                      select r).Single<Restaurant>().Name;

But I received the error Sequence contains no elements. I checked the variable and it was returning a restaurant name. But I don't understand why I am receiving these errors.

3
  • 8
    Sequence contains no elements means there is no items in the query results. that's why SingleOrDefault() is returning null and you get a NullReferenceException. Check your query criteria. Commented Mar 7, 2014 at 19:50
  • Have you tried writing thw query like this: var RestaurantName = (from r in objCtx.Restaurants where r.id == item.restaurantid select r.Name).SingleOrDefault(); Commented Mar 7, 2014 at 19:52
  • Almost all cases of NullReferenceException are the same. Please see "What is a NullReferenceException in .NET?" for some hints. Commented Mar 7, 2014 at 19:59

6 Answers 6

4

The problem is that your linq query returns an empty collection:

from r in objCtx.Restaurants
where r.id == item.restaurantid
select r

When you call SingleOrDefaultin your first example, it returns null (ie the default value). You receive an object reference not set ...because you're trying to invoke the Name property on a null reference.

In your second example you call Single. When you do that on a list with 0 or +1 elements, an exception will be thrown. (as you are experiencing).

The solution is to either make sure that you always retrieve a single instance, or to do a check before you access any properties on that object

Sign up to request clarification or add additional context in comments.

Comments

2

As others have said, your result set is empty. This will cause Single to fail (this is documented), and it will cause SingleOrDefault to return the default value for the given type (null in the case of a class).

In addition to the solutions presented in other answers (using null guards), here's another using more LINQ:

var RestaurantName = (from r in objCtx.Restaurants
                      where r.id == item.restaurantid
                      select r).DefaultIfEmpty(new Restaurant() { Name="None" })
                               .SingleOrDefault().Name;

DefaultIfEmpty will change the "default" value returned by SingleOrDefault from null to the supplied value. This way you can safely access the Name property. Depending on exactly how your Restaurant class is built, you may want to create the default value differently. You should be able to supply a default of something like new { Name = "None" }, as well, creating an anonymous object, but that's up to you.

Comments

0

The problem is that there are not items in the collection that fulfill the condition. SingleOrDefault returns null (for reference types), so that in the frst version you receive a NullReferenceException. Single throws an exception if there are no elements that are returned, that's why the second approach fails.

You need to check whether there are any results:

var restaurant = (from r in objCtx.Restaurants
                  where r.id == item.restaurantid
                  select r).SingleOrDefault<Restaurant>();
string restaurantName;
if (restaurant != null)
    restaurantName = restaurant.Name;
else
    restaurantName = string.Empty;

Comments

0

If, as you say, your second code sample (the one using Single) return no elements, then the first one (the one using SingleOrDefault) returned null. And you can't get the .Name property off of null.

I think you need to verify your query. Look at the data directly or perhaps even just loop through the data and see what the output is:

var restaurants = from r in objCtx.Restaurants
                  where r.id == item.restaurantid
                  select r;

foreach (var restaurant in restaurants)
{
    string name = restaurant.Name;
}

I'm guessing that the loop will never execute because its empty and you need to figure out what's wrong with your query.

If you need to handle the scenario where it might return no elements, then you just need an if check:

var restaurant = (from r in objCtx.Restaurants
                  where r.id == item.restaurantid
                  select r).SingleOrDefault<Restaurant>();

string restaurantName;
if (restaurant == null)
    restaurantName = string.Empty;
else
    restaurantName = restaurant.Name;

Comments

0

Try:

var RestaurantName = ((from r in objCtx.Restaurants
                          where r.id == item.restaurantid
                          select r).Any()) ? (from r in objCtx.Restaurants
                          where r.id == item.restaurantid
                          select r).SingleOrDefault<Restaurant>().Name : string.empty;

Comments

-1
var restaurantName = new Restaurant();

restaurantName = (from r in objCtx.Restaurants
                      where r.id == item.restaurantid
                      select r).SingleOrDefault(); 

var RestaurantName = (restaurantName != null) ? restaurantName.Name : "";

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.