linq where子句和count导致null异常

时间:2010-03-23 04:10:50

标签: c# linq

下面的代码有效,除非p.School.SchoolName结果为null,在这种情况下会导致NullReferenceException。

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

ExistingUsers是一个用户列表:

public List<User> ExistingUsers;

这是stacktrace的相关部分:

  

System.NullReferenceException:未将对象引用设置为对象的实例。

     

在System.Linq.Enumerable.WhereListIterator 1.MoveNext()
at System.Linq.Enumerable.Count[TSource](IEnumerable
1来源)

我该如何处理where where子句?

非常感谢。

4 个答案:

答案 0 :(得分:25)

我怀疑p.School为空,而不是SchoolName。只需在访问SchoolName之前添加空检查。此外,使用Any()检查是否有任何结果而不是Count() > 0,除非您真的需要计数。这样做效果更好,因为如果存在任何项目,并非所有项目都会被迭代。

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

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

答案 1 :(得分:1)

对于所有数据库可为空的列,我们应该添加空检查或执行简单的比较a == b而不是a.ToLower() == b.ToLower()或类似的字符串操作。
我的观察如下:
当它们通过Enumerable LINQ Query进行迭代以与输入字符串/值进行比较时,任何空值(数据库列)及其上的操作都会引发异常,但Enumerable变为NULL,尽管查询不为null。

答案 2 :(得分:0)

如果您想获得空值(所有学生,是否有学校)使用左连接。

MSDN上有一个很好的例子

答案 3 :(得分:0)

如果我没记错的话(目前不在我的开发者电脑上并且无法使用Reflector检查),使用==运算符会调用instance implementation string.Equals(string),而不是静态实现String.Equals(string, string)

假设您的问题是SchoolName为空,正如您所建议的那样,请尝试以下操作:

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

当然,其他答案的评论也很重要:

  • 使用Any()代替Count() > 0通常会效果更好
  • 如果p.School为空,则需要额外检查

希望这有帮助。