2009-09-02 32 views
29

Tôi đang cố gắng để làm một truy vấn như vậy ...LINQ cú pháp nơi chuỗi giá trị không phải là null hoặc rỗng

query.Where(x => !string.IsNullOrEmpty(x.PropertyName)); 

nhưng nó không thành công ...

như vậy vì bây giờ tôi đã triển khai sau, hoạt động ...

query.Where(x => (x.PropertyName ?? string.Empty) != string.Empty); 

có cách nào tốt hơn (bản địa hơn) mà LINQ xử lý?

EDIT

xin lỗi! không bao gồm nhà cung cấp ... Điều này đang sử dụng LINQ to SQL

+0

Nhà cung cấp LINQ nào? SQL, thực thể, đối tượng, ...? –

+0

Tôi cho rằng nhà cung cấp LINQ của bạn không hỗ trợ String.IsNullOrEmpty() gây ra một NotSupportedException. –

+0

Bạn có thể giải thích tại sao nó không thành công? Những giá trị nào nhận được thông qua đó bạn không mong đợi để làm cho nó. Tôi không thể nhìn thấy bất cứ điều gì sai với mã cụ thể này (hoặc những gì sẽ phân biệt nó từ ví dụ thứ hai). – JaredPar

Trả lời

37

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=367077

Tuyên Bố Vấn đề
Có thể viết LINQ to SQL mà được tất cả các hàng có một trong hai null hoặc một chuỗi rỗng trong một lĩnh vực nhất định, nhưng nó không thể sử dụng string.IsNullOrEmpty làm nó, mặc dù nhiều phương thức chuỗi khác ánh xạ tới LINQ to SQL. đề xuất giải pháp phép string.IsNullOrEmpty trong LINQ to SQL mệnh đề where để hai truy vấn này có kết quả tương tự:

var fieldNullOrEmpty = 
from item in db.SomeTable 
where item.SomeField == null || item.SomeField.Equals(string.Empty) 
select item; 

var fieldNullOrEmpty2 = 
from item in db.SomeTable 
where string.IsNullOrEmpty(item.SomeField) 
select item; 

khác Reading:
1. DevArt
2. Dervalp.com
3.StackOverflow Post

2

Điều này sẽ hoạt động tốt với LINQ to Objects. Tuy nhiên, một số nhà cung cấp LINQ gặp khó khăn khi chạy các phương thức CLR như một phần của truy vấn. Điều này đặc biệt đúng với một số nhà cung cấp cơ sở dữ liệu.

Vấn đề là các nhà cung cấp DB cố di chuyển và biên dịch truy vấn LINQ làm truy vấn cơ sở dữ liệu, để ngăn chặn kéo tất cả các đối tượng trên dây. Đây là một điều tốt, nhưng đôi khi hạn chế sự linh hoạt trong các biến vị ngữ của bạn.

Thật không may, không kiểm tra tài liệu của nhà cung cấp, thật khó để biết chính xác những gì sẽ hoặc sẽ không được hỗ trợ trực tiếp trong nhà cung cấp. Có vẻ như nhà cung cấp của bạn cho phép so sánh, nhưng không cho phép kiểm tra chuỗi. Tôi đoán rằng, trong trường hợp của bạn, điều này có lẽ là về một cách tiếp cận tốt như bạn có thể nhận được. (Nó thực sự không khác với kiểm tra IsNullOrEmpty, ngoài việc tạo ra thể hiện "string.Empty" để so sánh, nhưng đó là nhỏ.)

14

Điều này sẽ không thất bại trên Linq2Objects, nhưng nó sẽ thất bại cho Linq2SQL, vì vậy tôi am giả sử rằng bạn đang nói về nhà cung cấp SQL hoặc một cái gì đó tương tự.

Lý do phải làm với cách nhà cung cấp SQL xử lý biểu thức lambda của bạn. Nó không lấy nó như một hàm Func<P,T>, nhưng là một biểu thức Expression<Func<P,T>>. Nó lấy cây biểu thức đó và dịch nó thành một câu lệnh SQL thực tế, nó sẽ gửi đến máy chủ.

Dịch giả biết cách xử lý các toán tử cơ bản nhưng không biết cách xử lý các phương thức trên đối tượng. Nó không biết rằng IsNullOrEmpty(x) dịch sang return x == null || x == string.empty. Điều đó phải được thực hiện một cách rõ ràng cho việc dịch sang SQL diễn ra.

+1

Giải thích tuyệt vời - cảm ơn! –

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