2010-02-21 22 views
5

Làm cách nào tôi có thể chỉ định điều kiện trong trường hợp vị từ trong LINQ mà không nhận ngoại lệ tham chiếu null. Ví dụ, nếu q là một IQueryable thế nào có thể tôi thích:Trường hợp Predicates trong LINQ

Expression<Func<ProductEntity,bool>> predicate = p => !search.CategoryId.HasValue || (search.CategoryId.HasValue && search.CategoryId == p.CategoryId); 

var q2 = q.Where(predicate); 

Đây search là một đối tượng chứa điều kiện tìm kiếm có thể có thể có hoặc không có thể được thiết lập như search.CategoryId có thể không được thiết lập, nhưng nếu nó là Tôi muốn nhận được các sản phẩm được thiết lập bởi điều kiện đó.

Khi tôi làm điều này, tôi nhận được ngoại lệ tham chiếu null.

Trả lời

7

Bạn có thể sử dụng null-coalescing operator?? để thay thế giá trị null có thể có bằng giá trị mặc định. Các bộ sau đây sẽ cố gắng khớp với search.Category nếu nó tồn tại hoặc chỉ đơn giản là tạo ra một biểu thức "luôn đúng". Điều này sẽ được tối ưu hóa bởi bất kỳ nhà cung cấp truy vấn LINQ nào tốt (ví dụ: LinqToSql).

Expression<Func<ProductEntity,bool>> predicate = (p => (search.CategoryId ?? p.CategoryId) == p.CategoryId)); 

var q2 = q.Where(predicate); 

Một khả năng khác là tự động soạn một vị từ truy vấn bằng cách sử dụng PredicateBuilder. Đó là cách tôi làm điều đó cho các tìm kiếm với một mô hình tương tự như bạn sử dụng:

var predicate = PredicateBuilder.True<Order>(); 

if (search.OrderId)) 
{ 
    predicate = predicate.And(a => SqlMethods.Like(a.OrderID, search.OderID); 
} 
// ... 
var results = q.Where(predicate); 
3

Hãy phân tích dòng:

Expression<Func<ProductEntity,bool> predicate = p => !search.CategoryId.HasValue 
     || (search.CategoryId.HasValue && search.CategoryId == p.CategoryId) 
var q2 = q.Where(predicate); 

Vì vậy, có bao nhiêu cách chúng tôi có thể nhận được null vấn đề?

  • search (bạn "bắt" biến) có thể null
  • p có thể là null, có nghĩa là có một null trong danh sách
  • bạn đã xử lý trường hợp search.CategoryIdnull (Nullable<T>)
  • nhưng có thể p.CategoryId (danh mục trên bản ghi trong danh sách) là null (Nullable<T>) - howe ver, tôi không chắc chắn rằng điều này sẽ gây ra một NullReferenceException
  • q (danh sách/nguồn) có thể là null

Vì vậy: trong 5 tùy chọn bạn đã loại bỏ 1; nhìn 4 người kia? Có cũng là khả năng nhất định rằng vấn đề là do một cái gì đó vô hình không được hiển thị trong mã; ví dụ như get có thể là:

public int? CategoryId { 
    get {return innerObject.CategoryId;} 
} 

innerObject có thể null; nếu bạn loại bỏ 4 khác (khá dễ dàng để làm), hãy nhìn vào điều này như là một phương sách cuối cùng.

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