[c#] linq의 let 키워드가 into 키워드보다 낫습니까?

나는 현재 LINQ를 닦고 let있으며 into키워드 와 키워드 사용의 차이점을 이해하려고 노력하고 있습니다. 지금까지 내가 이해 let하는 한 into키워드 는 키워드 보다 더 나은 것 같습니다 .

into키워드는 본질적으로 하나가 투사 한 후 쿼리를 계속할 수 있습니다. (단지 내가 그룹 가입을 언급하지 않는다는 것을 명시하고 싶습니다.)

이름 배열이 주어지면 다음을 수행 할 수 있습니다.

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

그것은 선택의 결과를 가져와으로 배치 noVowel한 후 하나를 추가로 도입 할 수 있도록 변수 where, orderby그리고 select절을. noVowel변수가 생성 되면 n변수를 더 이상 사용할 수 없습니다.

반면에 let키워드는 임시 익명 유형을 사용하여 한 번에 둘 이상의 변수를 재사용 할 수 있습니다.

다음을 수행 할 수 있습니다.

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

모두 noVoweln변수 (나는이 경우에는 사용하지 않은 경우에도) 사용할 수 있습니다.

차이점은 알 수 있지만 이전 변수가 쿼리의 후반 부분에서 사용될 수 없도록 명시 적으로 확인하지 않는 한 into키워드 대신 키워드 를 사용하려는 이유를 이해할 수 없습니다 let.

그렇다면 두 키워드가 모두 존재하는 이유가 있습니까?



답변

네, 당신이 말했듯이 그들은 다른 일을하기 때문입니다.

select ... into하나의 쿼리 전체를 효과적으로 격리하고 새 쿼리에 대한 입력으로 사용할 수 있습니다. 개인적으로 저는 일반적으로 두 가지 변수를 통해이 작업을 수행하는 것을 선호합니다.

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

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

(이 경우에는 두 줄로 된 점 표기법을 사용하지만 무시합니다 …)

위의 예에 따라 쿼리를 두 개로 사용 하거나 분할 할 때 쿼리의 이전 부분의 전체 수하물을 원하지 않는 경우가 많습니다 select ... into. 이는 쿼리의 이전 부분을 사용하지 않아야 할 때 사용할 수 없음을 의미 할뿐만 아니라 진행중인 작업을 단순화합니다. 물론 각 단계에서 진행되는 복사 작업이 잠재적으로 적다는 것을 의미합니다.

반면에, 당신이 때 않는 문맥의 나머지 부분을 유지하려면, let더 의미가 있습니다.


답변

주요 차이점은 let변수를 컨텍스트 / 범위에 삽입하는 것입니다. 여기서 into새 컨텍스트 / 범위를 만듭니다.


답변

DB 측의 차이점을 알고 싶어서 2 개의 Entity Framework 쿼리를 작성했습니다.

  • 허락하다

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

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

생성 된 SQL은 거의 동일합니다 . SQL은 완벽하지 않으며 동일한 문자열 프로세스 코드가 2 곳 (where 및 select)에서 반복됩니다.

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

다음은 LINQ-to-SQL에서 생성 된 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

Linq-to-SQL이 Entity Framework보다 똑똑한 것 같습니다 . 문자열 프로세스는 한 번만 수행됩니다.


답변

leppie의 대답의 시각화 버전 . 알 수 있듯이 컴파일러 into는 첫 번째 변수에 액세스 할 때 후자 와 달리 쿼리에서 오류를 생성 합니다.

여기에 이미지 설명 입력


답변