2009-03-13 23 views
84

Tôi hiện đang đánh lừa LINQ và đang cố gắng hiểu sự khác biệt giữa let và sử dụng từ khóa into. Cho đến nay, từ khóa let có vẻ tốt hơn từ khóa into theo như hiểu biết của tôi.Từ khóa của linq có tốt hơn từ khóa của nó không?

Từ khóa into về cơ bản cho phép một người tiếp tục truy vấn sau khi chiếu. (Chỉ muốn nói rõ rằng tôi không đề cập đến một cho nhóm tham gia.)

Với một loạt các tên nó cho phép một người làm như sau:

var intoQuery = 
    from n in names 
    select Regex.Replace(n, "[aeiou]", "") 
    into noVowel 
    where noVowel.Length > 2 
    select noVowel; 

Phải mất kết quả của chọn và đặt nó vào biến số noVowel, sau đó cho phép một người giới thiệu thêm các điều khoản where, orderbyselect. Khi biến số noVowel được tạo, biến số n không còn khả dụng nữa. Mặt khác, let từ khóa sử dụng các loại ẩn danh tạm thời để cho phép bạn sử dụng lại nhiều biến cùng một lúc.

Bạn có thể làm như sau:

var letQuery = 
    from n in names 
    let noVowel = Regex.Replace(n, "[aeiou]", "") 
    where noVowel.Length > 2 
    select noVowel; 

Cả noVoweln biến có sẵn để sử dụng (mặc dù tôi đã không sử dụng nó trong trường hợp này).

Trong khi tôi có thể thấy sự khác biệt, tôi không thể hiểu tại sao người ta muốn sử dụng từ khóa into trên từ khóa let trừ khi một cách rõ ràng muốn đảm bảo rằng các biến trước đó không thể được sử dụng trong các phần sau của truy vấn.

Vì vậy, có lý do chính đáng nào khiến cả hai từ khóa đều tồn tại?

+0

Đây có phải là lỗi đánh máy trong ví dụ 'let' -' where noVowel', 'noVowel' trong trường hợp đó là gì? – sll

Trả lời

82

Có, bởi vì họ đang làm những việc khác nhau, như bạn đã nói.

select ... into tách riêng toàn bộ một truy vấn và cho phép bạn sử dụng nó làm đầu vào cho truy vấn mới. Cá nhân tôi thường thích để làm điều này thông qua hai biến:

var tmp = from n in names 
      select Regex.Replace(n, "[aeiou]", ""); 

var noVowels = from noVowel in tmp 
       where noVowel.Length > 2 
       select noVowel; 

(Phải thừa nhận rằng trong trường hợp này tôi sẽ làm điều đó với ký hiệu dấu chấm trong hai dòng, nhưng lờ đi mà ...)

Thông thường bạn don 't muốn toàn bộ hành lý của phần trước của truy vấn - tức là khi bạn sử dụng select ... into hoặc chia truy vấn thành hai theo ví dụ trên. Điều đó không chỉ có nghĩa là các phần trước của truy vấn không thể được sử dụng khi chúng không được, nó đơn giản hóa những gì đang xảy ra - và tất nhiên nó có nghĩa là có khả năng ít sao chép xảy ra ở mỗi bước.

Mặt khác, khi bạn làm muốn giữ phần còn lại của ngữ cảnh, let có ý nghĩa hơn.

+9

Việc sử dụng một hay khác có ảnh hưởng đến SQL được tạo không? –

43

Sự khác biệt chính là let đưa biến vào ngữ cảnh/phạm vi, trong đó into tạo ngữ cảnh/phạm vi mới.

0

Muốn biết sự khác biệt về phía DB, đã viết 2 Truy vấn khung thực thể.

  • Hãy

    from u in Users 
    let noVowel = u.FirstName.Replace("a","").Replace("e","").Replace("i","") 
    where noVowel.Length >5 
    select new {u.FirstName, noVowel} 
    
  • Into

    from u in Users 
    select u.FirstName.Replace("a","").Replace("e","").Replace("i","") 
    into noVowel 
    where noVowel.Length >5 
    select noVowel 
    

Các SQLs tạo ra gần như giống hệt nhau . SQL không hoàn hảo, cùng một quy trình xử lý chuỗi được lặp lại trên 2 địa điểm (ở đâu và chọn).

SELECT 1 AS [C1], [Extent1].[FirstName] AS [FirstName], 
REPLACE(REPLACE(REPLACE([Extent1].[FirstName], N'a', N''), N'e', N''), N'i', N'') AS [C2] 
FROM [dbo].[User] AS [Extent1] 
WHERE (CAST(LEN(REPLACE(REPLACE(REPLACE([Extent1].[FirstName], N'a', N''), N'e', N''), N'i', N'')) AS int)) > 5 
GO 

SELECT 
REPLACE(REPLACE(REPLACE([Extent1].[FirstName], N'a', N''), N'e', N''), N'i', N'') AS [C1] 
FROM [dbo].[User] AS [Extent1] 
WHERE (CAST(LEN(REPLACE(REPLACE(REPLACE([Extent1].[FirstName], N'a', N''), N'e', N''), N'i', N'')) AS int)) > 5 

Đây là SQL được tạo ra bởi LINQ-to-SQL

-- Region Parameters 
DECLARE @p0 NVarChar(1000) = 'a' 
DECLARE @p1 NVarChar(1000) = '' 
DECLARE @p2 NVarChar(1000) = 'e' 
DECLARE @p3 NVarChar(1000) = '' 
DECLARE @p4 NVarChar(1000) = 'i' 
DECLARE @p5 NVarChar(1000) = '' 
DECLARE @p6 Int = 5 
-- EndRegion 
SELECT [t1].[FirstName], [t1].[value] AS [noVowel] 
FROM (
    SELECT [t0].[FirstName], REPLACE(REPLACE(REPLACE([t0].[FirstName], @p0, @p1), @p2, @p3), @p4, @p5) AS [value] 
    FROM [User] AS [t0] 
    ) AS [t1] 
WHERE LEN([t1].[value]) > @p6 
GO 

-- Region Parameters 
DECLARE @p0 NVarChar(1000) = 'a' 
DECLARE @p1 NVarChar(1000) = '' 
DECLARE @p2 NVarChar(1000) = 'e' 
DECLARE @p3 NVarChar(1000) = '' 
DECLARE @p4 NVarChar(1000) = 'i' 
DECLARE @p5 NVarChar(1000) = '' 
DECLARE @p6 Int = 5 
-- EndRegion 
SELECT [t1].[value] 
FROM (
    SELECT REPLACE(REPLACE(REPLACE([t0].[FirstName], @p0, @p1), @p2, @p3), @p4, @p5) AS [value] 
    FROM [User] AS [t0] 
    ) AS [t1] 
WHERE LEN([t1].[value]) > @p6 

vẻ LINQ-to-SQL là thông minh hơn hơn Entity Framework, quy trình chuỗi thực hiện một lần duy nhất.

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