I have the following code which generates a null reference exception when I provide a null argument to the PerformQuery method.
public class MyObject
{
public Guid Guid { get; private set; }
}
public class TableObject
{
// This is a Guid stored as a string
public string Hash { get; set; }
}
public DataContext context;
public TableObject PerformQuery(MyObject obj)
{
return context.TableObjects.FirstOrDefault(tableObject =>
obj != null &&
// Why is this side of the condition being evaluated if obj is null?
string.Equals(obj.Guid.ToString(), tableObject.Hash));
}
I'm sure that the TableObject is not null. How could it? and It's property Hash is not nullable, so it shouldn't be null either (though I've checked both for null with no improvement).
I have solved the issue myself by calculating the Guid string that I am searching fore before executing the query, but I'm curious as to why LINQ continues to evaluate the conditional even if obj is null. Is this because of LINQ to SQL optimizations that the booleans are not evaluated in the same order as if it was a traditional if else statement?
You should evaluate local objects before entering the LINQ to SQL query. The database has no way to know if your object is null.
public TableObject PerformQuery(MyObject obj) {
if (obj == null) {return null;}
// also pull this out of the LINQ logic.
string objGuid = obj.Guid.ToString();
return context.TableObjects.FirstOrDefault(tableObject =>
string.Equals(objGuid, tableObject.Hash));
}
This is because linq-to-sql tries to translate the whole expression into SQL. So the null object reference occurs during this translation. You can tell because no SQL is even sent to the database.
The solution is to evaluate obj.Guid before you compose the query (as in @ps2goat's answer, but the reason is slightly different).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With