I have a userList, some users don’t have a name (null). If I run the first LINQ query, I got an error saying “object reference not set to an instance of an object” error.
var temp = (from a in userList
where ((a.name == "john") && (a.name != null))
select a).ToList();
However, if I switch the order by putting the checking for null in front, then it works without throwing any error:
var temp = (from a in userList
where ((a.name != null) && (a.name == "john"))
select a).ToList();
Why is that? If that’s pure C# code (not LINQ), I think both would be the same. I don’t have SQL profiler, I am just curious what will be the difference when they are being translated on SQL level.
In C# the
&&operator is short-circuiting so if the first condition returns false, the second condition is not executed at all. From MSDN:The
||operator behaves in a similar way, except that it doesn’t evaluate its second argument if the first returns true.I don’t think this is the full story though. The rest of my post covers the following points:
You can easily view the generated SQL in Visual Studio without needing a SQL profiler. You can hover your mouse over a LINQ to SQL query object and it will display the SQL. Or you can use the
DataContext.Logto log the SQL statements, for example like this:You can also log to a file or even to
Console.Out:Doing this you can see that the query looks something like this, although you will likely have more columns in the select list:
Another point is that your query should not generate an error. Even if
a.nameis null,a == "john"should still work – it will just return false.Lastly, there is a difference between how C# normally works and how LINQ to SQL works. You shouldn’t get a null exception from the database. To demonstrate this I will make a small modification to your query – adding a
ToStringaftera.Name:Now this fails for Linq to Objects with a NullReferenceException, but it works with LINQ to SQL without throwing an exception. So I suspect that you have loaded all items from the database into memory and are filtering locally. In other words maybe you have something like this:
instead of the following which would allow the database to do the filtering:
So I suspect there is more to this question than meets the eye. Perhaps you can provide more details.