Is linq's let keyword better than its into keyword?

前端 未结 4 1914
鱼传尺愫
鱼传尺愫 2020-12-22 22:09

I\'m currently brushing up on LINQ and am trying to comprehend the difference between the let and using the into keyword. So far the let

相关标签:
4条回答
  • 2020-12-22 22:49

    Yes, because they're doing different things, as you've said.

    select ... into effectively isolates the whole of one query and lets you use it as the input to a new query. Personally I usually prefer to do this via two variables:

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

    (Admittedly in this case I would do it with dot notation in two lines, but ignoring that...)

    Often you don't want the whole baggage of the earlier part of the query - which is when you use select ... into or split the query in two as per the above example. Not only does that mean the earlier parts of the query can't be used when they shouldn't be, it simplifies what's going on - and of course it means there's potentially less copying going on at each step.

    On the other hand, when you do want to keep the rest of the context, let makes more sense.

    0 讨论(0)
  • 2020-12-22 22:57

    Wanting to know the difference on DB side, wrote 2 Entity Framework queries.

    • Let

      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
      

    The generated SQLs are almost identical. The SQL is not perfect, same string process code are repeated on 2 places (where and 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
    

    Here is the SQL generated by 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
    

    Seems Linq-to-SQL is smarter than Entity Framework, string process performed only once.

    0 讨论(0)
  • 2020-12-22 22:59

    Visualized version of leppie's answer. As can be seen, the compiler yields error in the query with into unlike the latter one as accessing to first variable.

    0 讨论(0)
  • 2020-12-22 23:09

    The primary difference is the let injects the variable into the context/scope, where into creates a new context/scope.

    0 讨论(0)
提交回复
热议问题