2012-07-10 39 views
5

Chúng tôi có một số dự án trong VB.Net, sử dụng .Net Framework 4 và LINQ to Entities cho nhiều truy vấn SQL của chúng tôi. Chuyển sang EF là một sự thay đổi mới cho chúng tôi (sử dụng nó trong khoảng 4-6 tháng) và có sự ủng hộ của quản lý cấp cao vì chúng tôi có thể viết mã nhanh hơn rất nhiều. Chúng tôi vẫn sử dụng rất nhiều procs được lưu trữ, nhưng chúng tôi thậm chí còn thực thi chúng thông qua LINQ to Entities.VB.Net LINQ to Entities So sánh Null - 'Không có gì' hoặc '= Không có gì'?

Tôi hy vọng xóa một số nhầm lẫn và tôi không thể tìm thấy câu trả lời trực tiếp có ý nghĩa. Chúng tôi có một số truy vấn mà chúng tôi muốn các bản ghi trong đó một trường cụ thể có giá trị NULL. Đây là những lựa chọn truy vấn đơn giản, không có uẩn hoặc trái tham gia vv Microsoft khuyến cáo giao diện truy vấn cái gì đó như MSDN Link này:

dim query = from a in MyContext.MyTables 
Where a.MyField = Nothing 
Select a 

Tôi có một số dự án mà tôi thực hiện chính xác này và nó hoạt động tuyệt vời, không có cảnh báo trong IDE . Gần đây, một dự án mới đã được tạo bởi một nhà phát triển khác và khi anh ta kiểm tra null như trên, tất cả chúng ta đều nhận được cảnh báo này trong IDE:

Cảnh báo 1 Biểu thức này sẽ luôn luôn đánh giá Không có gì (do truyền null từ toán tử bằng). Để kiểm tra xem giá trị là null xem xét sử dụng 'Không có gì'.

So sánh các dự án, tùy chọn rõ ràng và tùy chọn nghiêm ngặt được bật cho từng loại. Nếu chúng ta bỏ qua cảnh báo, chúng ta sẽ có được bộ bản ghi chính xác mà chúng ta đang tìm kiếm khi ứng dụng chạy. Cảnh báo sẽ biến mất nếu tôi thay đổi dấu = thành IS. Nhưng tại sao cảnh báo này lại xuất hiện trong một dự án chứ không phải những dự án khác? Nó gây nhầm lẫn khi ngay cả trên MSDN có những ví dụ bằng cách sử dụng toán tử equals.

+0

VB.NET LINQ cũng có từ khóa 'Equals'. Tôi không có cách nào để kiểm tra nó, nhưng có thể thử thay vào đó? 'Where a.MyField Equals Nothing ' –

+0

@Cory: Đó là một từ khóa theo ngữ cảnh chỉ được sử dụng trong mệnh đề' Tham gia' (AFAIK). Tôi không nghĩ rằng bạn có thể sử dụng nó ở bất cứ nơi nào khác. –

Trả lời

2

Tôi tin rằng những gì bạn thấy ở đây là MyField là loại Nullable(Of T). Có khả năng nguyên thủy Integer, Single, v.v ...

Lý do bạn thấy cảnh báo này là do trình biên dịch kích hoạt toán tử bình đẳng bình thường cho loại nguyên thủy cho phiên bản Nullable(Of T). Đó là bản chất thực thi

Dim myField As Integer? = a.MyField 
Dim other As Integer? = Nothing 
If myField = other Then 
... 
End If 

vấn đề sau đây mặc dù là khi Integer? có giá trị Nothing nó sẽ không so sánh bằng với bất cứ điều gì. Do đó, mệnh đề Where ở trên sẽ luôn trả về False. Trình biên dịch đang cố gắng cảnh báo bạn về góc có vấn đề này của Nullable(Of T) và đẩy bạn đến kiểm tra Is Nothing sẽ xác định xem a.MyField có giá trị không null hay không.

Bài viết trên blog này có giải thích rất chi tiết về lý do cảnh báo này được tạo và tất cả các cơ chế đằng sau nó. Bài viết được viết cho C# nhưng tiền đề cơ bản cũng được áp dụng cho VB.Net.

+0

Vì vậy, nếu tôi hiểu điều này đúng, dấu bằng được làm việc trong một truy vấn vì trường không phải là rỗng nhưng là một vấn đề trong truy vấn khác vì nó không có giá trị, do đó yêu cầu cú pháp khác. –

+0

@ChrisJones chính xác. Thông thường bạn có thể sử dụng '=' với giá trị nullable. So sánh với 'Nothing' mặc dù sẽ luôn trả về' False' mặc dù trình biên dịch đưa ra cảnh báo về nó – JaredPar

+0

Chơi với điều này nhiều hơn một chút, tôi có thể làm = Không có gì để chuỗi trường không có trong cơ sở dữ liệu, nhưng không phải dữ liệu khác các loại và có thể sử dụng là Không có gì hoặc thành viên HasValue mà Afshin đã đề cập. Cảm ơn bạn đã làm sáng tỏ điều này. –

5

cột tạo nên một Nullable(Of T)

Vì vậy, bạn có thể kiểm tra nếu trường đó có giá trị hay không như thế này:

dim query = from a in MyContext.MyTables 
Where Not a.MyField.HasValue 
Select a 
+0

Tôi đã thử điều này trên một số loại dữ liệu và nó sẽ không hoạt động trên các giá trị chuỗi. Tôi đã có thể sử dụng thành viên HasValue trên các kiểu dữ liệu số nguyên, ngày tháng và dữ liệu boolean. –

0

Ít nhất trong LINQ to đối tượng bạn có thể sử dụng thay thế này:

Nullable(Of Integer).Equals(a, b) 

Điều này làm việc tốt với cả hai, hoặc là không có giá trị nào trong hai giá trị này là Không có gì.