简体   繁体   English

linq where子句和count导致null异常

[英]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. 除非p.School.SchoolName结果为null,否则下面的代码有效,在这种情况下,它会导致NullReferenceException。

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

ExistingUsers is a list of users: ExistingUsers是一个用户列表:

public List<User> ExistingUsers;

Here is the relevant portion of the stacktrace: 这是stacktrace的相关部分:

System.NullReferenceException: Object reference not set to an instance of an object. System.NullReferenceException:未将对象引用设置为对象的实例。

at System.Linq.Enumerable.WhereListIterator 1.MoveNext()
at System.Linq.Enumerable.Count[TSource](IEnumerable
在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)
1.MoveNext()
at System.Linq.Enumerable.Count[TSource](IEnumerable
1 source)

How should I handle this where clause? 我应该如何处理这个where子句?

Thanks very much in advance. 首先十分感谢。

I suspect p.School is null, not SchoolName . 我怀疑p.School为空,不SchoolName Simply add a null check before accessing SchoolName . 只需在访问SchoolName之前添加一个空检查。 Also, use Any() to check if there are any results instead of Count() > 0 unless you're really in need of the count. 另外,使用Any()来检查是否有任何结果而不是Count() > 0除非你真的需要计数。 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. 对于所有数据库可空列,我们应该添加空检查或进行简单的比较a == b而不是a.ToLower() == b.ToLower()或类似的字符串操作。
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. 当它们通过Enumerable LINQ Query迭代以与输入字符串/值进行比较时,任何空值(数据库列)及其上的操作都会引发异常,但Enumerable变为NULL,尽管查询不为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 在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) . 如果我没记错的话(目前不在我的开发人员PC上并且无法使用Reflector检查),使用==运算符会导致调用实例实现 string.Equals(string) ,而不是静态实现String.Equals(string, string)

Assuming that your problem is due to SchoolName being null, as you suggest, try this: 假设你的问题是由于SchoolName为null,正如你的建议,试试这个:

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 使用Any()而不是Count() > 0通常会表现得更好
  • If p.School is the null, you'll need an extra check 如果p.School为null,则需要额外检查

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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