2012-06-18 24 views
7

Tôi có truy vấn LINQ sau:Tại sao LINQ-to-Entities đặt truy vấn này trong một lựa chọn phụ?

var queryGroups = (from p in db.cl_contact_event 
        select new Groups { inputFileName = p.input_file_name }).Distinct(); 

Những dịch như sau khi chạy:

SELECT 
[Distinct1].[C1] AS [C1], 
[Distinct1].[input_file_name] AS [input_file_name] 
FROM (SELECT DISTINCT 
     [Extent1].[input_file_name] AS [input_file_name], 
     1 AS [C1] 
     FROM [mel].[cl_contact_event] AS [Extent1] 
) AS [Distinct1] 

Bây giờ tôi khá chắc chắn rằng lý do có một phụ chọn là bởi vì tôi có truy vấn LINQ cơ sở được bao quanh bởi() và sau đó thực hiện .Distinct() nhưng tôi không biết đủ về LINQ để chắc chắn về điều này. Nếu đó thực sự là trường hợp là có một cách để cơ cấu lại/mã truy vấn của tôi để một phụ chọn không xảy ra?

Tôi biết rằng có lẽ dường như tôi chỉ chọn nit ở đây nhưng tôi chỉ tò mò thôi.

+0

Đó có phải là [tag: linq-to-sql], [tag: linq-to-entity] hay [tag: linq-to-nhibernate]? –

+0

@DannyVarod linq-to-thực thể Tôi tin rằng kể từ khi tôi đang sử dụng EF4 tôi đang truy vấn một cơ sở dữ liệu Sybase. – Kittoes0124

+0

Trong trường hợp đó, hãy thay đổi thẻ bạn đã sử dụng và cập nhật tiêu đề câu hỏi cho phù hợp. –

Trả lời

4

Trong trường hợp này, tôi nghi ngờ nguyên nhân gốc thực sự của truy vấn phụ là trình tạo kiểu ẩn danh. Bởi vì bạn không chọn một thực thể đã biết, mà là một đối tượng tùy ý được xây dựng từ các giá trị thực thể khác, trình phân tích cú pháp EF cần đảm bảo nó có thể tạo ra tập hợp các trường chính xác - cho dù từ một bảng đơn, các bảng đã nối, trường được tính toán, các truy vấn con, vv Trình phân tích cú pháp cây biểu thức rất tốt khi viết các câu lệnh SQL ra khỏi các truy vấn LINQ bất cứ khi nào có thể, nhưng nó không phải là toàn bộ. Nó xử lý các truy vấn một cách có hệ thống, điều đó sẽ luôn tạo ra các kết quả chính xác (theo nghĩa là bạn nhận được những gì bạn yêu cầu), mặc dù không phải lúc nào cũng là kết quả tối ưu.

Theo như viết lại truy vấn để loại bỏ lựa chọn phụ, trước hết: Tôi không thấy cách rõ ràng để làm như vậy loại bỏ loại ẩn danh và tạo kết quả chính xác. Quan trọng hơn, tuy nhiên, tôi sẽ không bận tâm. Các máy chủ SQL hiện đại như Sybase rất thông minh - thường thông minh hơn nhà phát triển - và rất giỏi trong việc tạo ra một kế hoạch truy vấn tối ưu trong truy vấn. Bên cạnh đó, EF yêu thích các truy vấn phụ, vì chúng là những cách rất tốt để viết các truy vấn phức tạp theo cách tự động. Bạn thường tìm thấy chúng ngay cả khi truy vấn LINQ của bạn không xuất hiện sử dụng chúng. Cố gắng để loại bỏ tất cả chúng từ các truy vấn của bạn sẽ nhanh chóng trở thành một bài tập trong vô ích.

+0

Cảm ơn phản hồi tuyệt vời và chi tiết. Tôi chỉ muốn chắc chắn rằng tôi đã không phạm sai lầm rõ ràng. – Kittoes0124

4

Tôi sẽ không lo lắng về tình huống cụ thể này chút nào. SQL Server (và rất có thể là bất kỳ cơ sở dữ liệu doanh nghiệp nào) sẽ tối ưu hóa báo cáo Chọn bên ngoài. Tôi sẽ giả thuyết rằng lý do câu lệnh SQL này được tạo ra bởi vì đây là câu lệnh chung nhất và có thể sử dụng lại được. Từ kinh nghiệm của tôi, điều này luôn xảy ra vào ngày Distinct().