Scott Selby
Scott Selby

Reputation: 9570

linq to sql Object Reference not set to an object

I have this query in Linq to Sql

decimal Rewards = db.User.FirstOrDefault(x => x.FFUserID == UserID).TotalCommission;

This query didn't find a record matching the userID , so obviously that's why the exception is being thrown. My question is - I thought that by using .FirstOrDefault() if there is no record it will return a Default Object - also thought that this default object will have a default value of 0.0M for TotalCommission . If that is not how it works then would would be the best way to write this , wanting it to be set to 0.0M for default.

is this the best?

decimal Rewards = db.User.FirstOrDefault(x => x.FFUserID == UserID)
                         .TotalCommission ?? 0.0M

Upvotes: 0

Views: 972

Answers (2)

p.s.w.g
p.s.w.g

Reputation: 149000

FirstOrDefault will return null when no item is found. So when you access the TotalCommission property, there's a chance of a NullReferenceException. I think you want to do this:

decimal Rewards = db.User.Where(x => x.FFUserID == UserID)
                         .Select(x => x.TotalCommission)
                         .FirstOrDefault();

Or in query syntax:

decimal Rewards =
    (from x in db.User
     where x.FFUserID == UserID
     select x.TotalCommission)
    .FirstOrDefault();

UPDATE: As of C# 6.0, you can now use the null-conditional operators to do something very similar to what you originally intended:

decimal Rewards = db.User.FirstOrDefault(x => x.FFUserID == UserID)
                        ?.TotalCommission ?? 0.0M

The ?. here will safely handle cases where given user ID is not found in the database and return a (decimal?)null. The plain old null-coalescing operator, ?? 0.0M, will give you the default value you expect.

Upvotes: 7

JSJ
JSJ

Reputation: 5691

decimal Rewards = db.User.FirstOrDefault(x => x.FFUserID == UserID)
                         .TotalCommission ?? 0.0M

here in this case you are sure about the TotalCommission will return value. but what about the object which is returned by the FirstOrDefault() you must care about that first then for the rest.

while you a using firstOrDefault there are chances that the result could be null. so we must check the nullable before access any property of typed object. otherwise you will surly Get NulllRefranceExcelption

so you must be care to check with null reference

alternatively you can do like this.

var result = db.User.FirstOrDefault(x => x.FFUserID == UserID);


if(result !=null)
{
 var mydata = result.TotalCommission;
}

here is the implemantation of FirstOrDefault Extension Method

     public static TSource FirstOrDefault</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
         ........
.........
                return default(TSource);
            }

So here you can see the result is default(TSource) which means if the TSource is refrance type this will return null or if the TSource is value type then this will return the default value of TSource. here are some sample implemantation of Default keyword.

 Console.WriteLine(default(Int32)); // Prints "0"
        Console.WriteLine(default(Boolean)); // Prints "False"
        Console.WriteLine(default(String)); // Prints nothing (because it is null)

Upvotes: 3

Related Questions