2009-11-04 36 views
7

Dường như tôi có thể viết một where x.a==1 && x.b==1 nhưSự khác nhau giữa nhiều điều khoản và điều hành && trong LINQ-to-SQL là gì?

where x.a==1 
where x.b==1 

Như tôi hiểu được những lượt sau vào .Where(x => x.a == 1).Where(x => x.b ==1), nhưng làm thế nào thực hiện điều này để dịch dB? Điều nào sẽ tốt hơn về mặt tối ưu hóa? Tôi luôn luôn có thể nhìn vào truy vấn được thực thi từ profiler nhưng điều đó khó có thể là một sự khái quát hóa nhưng giống như một quan sát thực nghiệm duy nhất, mà tôi không muốn dựa vào.

Đi qua không gian tên System.Linq với phản xạ là một tùy chọn khác nhưng sau đó chúng tôi sẽ bỏ lỡ cơ hội để tiết kiệm nhiều người từ việc dành thời gian cho cùng một điều. Tôi sẽ làm nếu tôi không nhận được bất kỳ câu trả lời nào.

+2

gần như trùng lặp của http://stackoverflow.com/questions/1648730/when-using-linq-what-is-the-difference-between-and-multiple-where-clauses –

+0

Tôi không tìm thấy điều đó trong tìm kiếm nhưng đây là LINQ-to-SQL cụ thể anyway. –

+0

tác động trên LINQ-to-Objects sẽ là hiển nhiên, tuy nhiên LINQ-to-SQL không rõ ràng. –

Trả lời

7

Ok đây là những phát hiện của tôi sau khi đi qua đầu ra Reflector trong một thời gian. LINQ-to-Đối tượng kết hợp liên tiếp where vị khi sử dụng WhereArrayIterator hoặc WhereListIterator làm cho nó gần như cư xử như & & điều hành, nhưng không phải là chính xác:

Khi bạn sử dụng x.a==1 && x.b==1 mệnh đề where chuyển thành một Func<TSource, bool> tìm kiếm như thế này:

bool daspredicate(TSource x) 
{ 
    return x.a==1 && x.b==1 
} 

Tuy nhiên, khi bạn sử dụng liên tiếp Điều khoản ở đâu có hình phạt hiệu suất nhỏ, ít nhất là từ khía cạnh không phải của JITted IL.Dưới đây là cách mã trông giống như sau khi kết hợp:

bool predicate1(TSource x) 
{ 
    return x.a==1; 
} 
bool predicate2(TSource x) 
{ 
    return x.b==1; 
} 
bool daspredicate(TSource x) 
{ 
    return predicate1(x) && predicate2(x); 
} 

Như bạn có thể thấy điều này liên quan đến phí gọi điện bổ sung. Điều này có thể khá tốn kém trừ khi JIT nhấn mạnh các chức năng. Tôi chắc chắn rằng nó làm một công việc tốt ở đó nhưng bây giờ chúng ta biết công việc của JIT trở nên dễ dàng hơn nhiều nếu chúng ta kết hợp bản Tuyên Bố của chúng ta, trừ khi cần thiết.

Về phía SQL của sự vật, các truy vấn giống nhau. Ngay cả trước khi thực hiện, trình gỡ lỗi đánh giá đối tượng truy vấn vào cùng một câu lệnh SQL. Tôi không thể đi quá xa trong không gian tên LINQ vì mọi thứ dường như phức tạp hơn nhiều, nhưng vì các truy vấn giống nhau, nên không có hình phạt không giống như ví dụ LINQ-to-objects ở trên.

EDIT: Tôi đã thấy các trường hợp có nhiều câu lệnh dẫn đến truy vấn con lồng nhau trên máy chủ SQL. Tôi nghĩ tốt hơn là nên gắn bó với những câu lệnh duy nhất bất cứ khi nào bạn có thể ở bên an toàn.

2

Tính năng LINQ to SQL có thể thực hiện đúng ở đây. Tôi hy vọng nó sẽ chuyển đổi hai mệnh đề "where" thành một mệnh đề SQL duy nhất với hai phần được nối cùng với "AND".

Hãy thử cả hai - nhưng tôi rất nghi ngờ bạn sẽ thấy bất kỳ sự khác biệt nào trong SQL được tạo.

IMO bạn nên luôn luôn xem SQL được tạo cho bất kỳ điều gì không tầm thường, nhưng cách LINQ hoạt động chắc chắn khuyến khích bạn xây dựng một truy vấn lớn bằng cách soạn nó ra các mệnh đề nhỏ - vì vậy tôi thực sự mong đợi nó chỉ cần làm việc.

+0

Có vẻ như vậy, cảm ơn! –

2

Phía DB chúng giống hệt nhau. Nó chỉ là một tác dụng phụ của LINQ-to-SQL là composable (tức là bạn có thể bắt đầu với một truy vấn và sau đó thêm các tiêu chí bổ sung vào nó, thay đổi dự báo, vv).

2

Mã:

where x.a==1 
where x.b==1 

hoặc

where x.a==1 && x.b==1 

là cú pháp đường cho C# anyway. Nó sẽ biên dịch như một chuỗi phương pháp LINQ của

Where(...).Where(...) 

cũng giống như bạn đoán nó có lẽ sẽ, vì vậy tôi thực sự nghi ngờ có bất kỳ sự khác biệt trong SQL tạo ra. Hãy thử sử dụng một công cụ như Resharper từ Jetbrains - nó thậm chí cung cấp intellisense cung cấp cho bạn sự lựa chọn để tự động chuyển đổi giữa hai để giúp bạn tiết kiệm thời gian viết lại nó để thử nghiệm.

Tùy chọn của tôi là viết các truy vấn đơn giản như chuỗi phương pháp, (ví dụ: chỉ có 1 bộ sưu tập/bảng liên quan và không có tham gia) và bất kỳ điều gì phức tạp hơn trong cú pháp đường LINQ rõ ràng hơn.

+0

Rõ ràng chúng không giống nhau, hãy xem câu trả lời của tôi. –

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