2010-03-23 27 views
14

Mã bên dưới hoạt động trừ khi p.School.SchoolName chỉ ra là rỗng, trong trường hợp này nó dẫn đến NullReferenceException.LINQ where khoản và kết quả đếm bằng ngoại lệ null

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

ExistingUsers là một danh sách người dùng:

public List<User> ExistingUsers; 

Dưới đây là phần có liên quan của stacktrace:

System.NullReferenceException: Đối tượng tham khảo không được đặt để một thể hiện của một đối tượng .

tại System.Linq.Enumerable.WhereListIterator 1.MoveNext()
at System.Linq.Enumerable.Count[TSource](IEnumerable
1 nguồn)

Làm thế nào tôi nên xử lý khoản này ở đâu?

Cảm ơn rất nhiều trước.

+5

Bạn có chắc là SchoolName rỗng và không phải p.School? –

+6

Như một lưu ý chung, thay vì làm IEnumerable.Count (vị ngữ)> 0, sử dụng IEnumerable.Any (vị ngữ). Điều này sẽ chấm dứt thực hiện cho trận đấu đầu tiên được tìm thấy, có khả năng sinh ra một tốc độ lớn lên. – recursive

+0

@Anthony: cảm ơn rất nhiều, tôi nghĩ bạn đúng về p.School là rỗng. – IntrepidDude

Trả lời

24

Tôi nghi ngờ p.School là không, không phải SchoolName. Chỉ cần thêm một kiểm tra rỗng trước khi truy cập SchoolName. Ngoài ra, hãy sử dụng Any() để kiểm tra xem có bất kỳ kết quả nào thay vì Count() > 0 trừ khi bạn thực sự cần tính. Điều này thực hiện tốt hơn vì không phải tất cả các mục đều được lặp lại nếu có.

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

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

Điều này làm việc như một say mê. Rất cám ơn, tôi đã học được! – IntrepidDude

0

Trong trường hợp bạn muốn nhận giá trị null (tất cả học sinh, với trường học hay không) Sử dụng kết nối trái.

Có một ví dụ điển hình trên MSDN

0

Nếu tôi nhớ chính xác (không phải ở máy tính phát triển của tôi vào lúc này và không thể kiểm tra với Reflector), sử dụng == kết quả điều hành trong việc kêu gọi các instance implementationstring.Equals(string), không phải là triển khai tĩnh String.Equals(string, string).

Giả sử rằng vấn đề của bạn là do SchoolName là null, như bạn đề nghị, hãy thử này:

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

Tất nhiên, ý kiến ​​của câu trả lời khác được tính là tốt:

  • Sử dụng Any() thay vì Count() > 0 nói chung sẽ hoạt động tốt hơn
  • Nếu p.School là số không, bạn sẽ cần séc phụ

Hy vọng điều này sẽ hữu ích.

1

Đối với tất cả các cột không có cơ sở dữ liệu, chúng tôi nên thêm kiểm tra null hoặc so sánh đơn giản a == b thay vì a.ToLower() == b.ToLower() hoặc các hoạt động chuỗi tương tự.
Quan sát của tôi như sau:
Khi chúng được lặp qua Enumerable truy vấn LINQ để so sánh với chuỗi đầu vào/giá trị, bất kỳ giá trị null (cột cơ sở dữ liệu) và hoạt động trên nó sẽ tăng ngoại lệ, nhưng Enumerable trở thành NULL, mặc dù truy vấn không phải là null.

Các vấn đề liên quan