简体   繁体   中英

linq where clause and count result in null exception

The code below works unless p.School.SchoolName turns out to be null, in which case it results in a NullReferenceException.

if (ExistingUsers.Where(p => p.StudentID == item.StaffID &&
                        p.School.SchoolName == item.SchoolID).Count() > 0)
{
    // Do stuff.
}

ExistingUsers is a list of users:

public List<User> ExistingUsers;

Here is the relevant portion of the stacktrace:

System.NullReferenceException: Object reference not set to an instance of an object.

at System.Linq.Enumerable.WhereListIterator 1.MoveNext()
at System.Linq.Enumerable.Count[TSource](IEnumerable
1.MoveNext()
at System.Linq.Enumerable.Count[TSource](IEnumerable
1.MoveNext()
at System.Linq.Enumerable.Count[TSource](IEnumerable
1 source)

How should I handle this where clause?

Thanks very much in advance.

I suspect p.School is null, not SchoolName . Simply add a null check before accessing SchoolName . Also, use Any() to check if there are any results instead of Count() > 0 unless you're really in need of the count. This performs better since not all items are iterated if any exist.

var result = ExistingUsers.Where(p => p.StudentID == item.StaffID
                            && p.School != null
                            && p.School.SchoolName == item.SchoolID)
                         .Any();

if (result) { /* do something */ }

For all database nullable columns, we should either add null check or do simple comparision a == b instead of a.ToLower() == b.ToLower() or similar string operations.
My observation as below:
As they get iterated through Enumerable of LINQ Query for comparision against with input string/value, any null value (of database column) and operations on it would raise exception, but Enumerable becomes NULL, though query is not null.

In the case where you want to get the null value (all the student, with school or not) Use left join.

There are a good example on MSDN

If I remember correctly (not at my developer PC at the moment and can't check with Reflector), using the == operator results in calling the instance implementation string.Equals(string) , not the static implementation String.Equals(string, string) .

Assuming that your problem is due to SchoolName being null, as you suggest, try this:

if (ExistingUsers.Where(
    p => p.StudentID == item.StaffID 
    && String.Equals( p.School.SchoolName, item.SchoolID)).Count() > 0)
{
    // Do stuff.
}

Of course, comments by other answers count as well:

  • Using Any() instead of Count() > 0 will generally perform better
  • If p.School is the null, you'll need an extra check

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM