2009-12-05 32 views
5

Tôi đang đọc giải thích mâu thuẫn về Linq để so sánh chuỗi Sql.LINQ to Sql trường hợp bình đẳng nhạy cảm

Khi tôi làm như sau:

from p in db.People 
    where p.UserName=username 
    select p 

username = "John"

tôi nhận được trường hợp kết quả không nhạy cảm chính xác. Là LINQ làm điều này theo mặc định hoặc là điều này xảy ra trong cơ sở dữ liệu SQL?

+0

Bạn có thiếu một số trích dẫn không? Thay đổi trường hợp tên biến không ảnh hưởng đến kết quả. –

+0

thats không phải là những gì tôi có nghĩa là nhìn thấy trên – zsharp

Trả lời

4

Tôi nghĩ rằng bạn nhận được các kết quả xung đột dựa trên những gì biến db của bạn trỏ đến và nơi so sánh thực sự được thực thi. Nếu có thể, linq sẽ xây dựng truy vấn và gửi nó đến máy chủ SQL. Nó có vẻ như bạn có thể buộc phân biệt dạng chữ bằng cách gọi

where p.UserName.ToLower()=username.ToLower() 
+1

Xin lỗi, nhưng đây là lời khuyên không tốt. p.UserName.ToLower() = username.ToLower() sẽ chuyển thành truy vấn SQL sẽ bắt buộc quét toàn bộ bảng. Điều đó không quan trọng nếu bảng "mọi người" nhỏ, nhưng nếu nó là một bảng lớn thì nó sẽ không thể sử dụng bất kỳ chỉ mục nào có thể bao gồm cột 'tên người dùng'. – KristoferA

1

Tùy thuộc vào cơ sở dữ liệu. SQL Server 2008 xử lý các chuỗi như phân biệt dạng chữ, bao gồm khi được sử dụng trong một biểu thức chỉ mục. Linq không làm điều đó.

Đọc on MSDN hoặc this article.

+2

Trường hợp nhạy cảm/insensitivity phụ thuộc vào collation bạn sử dụng trong cơ sở dữ liệu của bạn và/hoặc các cột liên quan (mặc định được thiết lập khi sql server được cài đặt, nhưng nó có thể được ghi đè ở một số nơi, xuống đến cấp độ cột). – KristoferA

3

truy vấn mẫu của bạn sẽ dịch một cái gì đó gần như thế này:

chọn [t0] .col1, [t0] .col2, ..., [ t0] .coln từ [schema]. [People] trong đó [t0] .UserName = @ p0

... giá trị trong biến tên người dùng sẽ được chuyển vào biến @ p0 sql. Như vậy, trường hợp nhạy cảm, độ nhạy giọng nói vv được kiểm soát bởi collation bạn đã thiết lập SQL Server instance/db/table/column của bạn để sử dụng. Nếu không được chỉ định ở bất kỳ nơi nào khác, thì collation mặc định của DB hoặc DB được sử dụng, nhưng collation có thể được chỉ định tất cả các con đường xuống đến mức cột.

Hầu hết mọi người chạy SQL Server với trường hợp không phân biệt chữ hoa chữ thường (CI) nhưng như tôi đã nói ở trên, nó có thể bị ghi đè trong DB vì vậy bạn chỉ cần kiểm tra xem bạn có gì ở đó. Điều này trái ngược với việc bạn làm tương tự như truy vấn L2O (LINQ to objects), trong trường hợp này, độ nhạy là trường hợp mặc định và bạn sẽ phải làm cho nó không phân biệt chữ hoa chữ thường bằng cách sử dụng ghi đè string.equals cho phép bạn chỉ định văn hóa và/hoặc không phân biệt chữ hoa chữ thường ...

+0

sẽ không sử dụng ghi đè string.equals có cùng một vấn đề mà bạn đã nhận xét về kết quả của tôi không? Buộc tất cả các hồ sơ đến bên LINQ để so sánh? –

+0

@ Jeff, Tham chiếu string.equals chỉ là sự so sánh giữa cách hoạt động của L2S và L2O, xin lỗi nếu tôi không rõ ràng về điểm đó. Nhưng có, nếu bạn kết hợp cả hai và thực hiện đánh giá ở phía máy khách như một truy vấn L2O thì nó sẽ không chỉ nhận được tất cả các bản ghi mà còn gửi chúng qua dây. Nói cách khác, sử dụng collation phải là chìa khóa ở đây. Ví dụ từ câu trả lời của bạn sẽ vẫn được đánh giá trong cơ sở dữ liệu, nhưng với chi phí bổ sung của việc quét bảng do trình bao bọc cuộc gọi hàm ở phía bên tay trái, nơi biến vị ngữ. – KristoferA

+0

Cảm ơn bạn đã phản hồi (Tôi đã +1 khi tôi đưa ra nhận xét trước đó) –

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