linq的let关键字比关键字更好吗?
我正在刷新LINQ,并试图理解let
和使用into
关键字之间的区别。 就我的理解而言,到目前为止, let
关键字似乎比into
关键字更好。
into
关键字本质上允许在投影之后继续查询。 (只是想明确指出,我不是指组join。)
给定一个名称的数组,它允许执行以下操作:
var intoQuery = from n in names select Regex.Replace(n, "[aeiou]", "") into noVowel where noVowel.Length > 2 select noVowel;
它将select的结果放到noVowel
variables中,然后允许引入附加的where
, orderby
和select
子句。 一旦noVowel
variables被创build, n
variables不再可用。
另一方面, let
关键字使用临时匿名types来允许您一次重用多个variables。
您可以执行以下操作:
var letQuery = from n in names let noVowel = Regex.Replace(n, "[aeiou]", "") where noVowel.Length > 2 select noVowel;
noVowel
和n
variables都可以使用(尽pipe在这种情况下我没有使用它)。
虽然我可以看到不同之处,但我不明白为什么要使用关键字let
关键字,除非明确地要确保以前的variables不能在查询的后面部分中使用。
那么,为什么这两个关键词都存在是否有很好的理由?
是的,因为他们正在做不同的事情,正如你所说的。
select ... into
有效隔离整个查询,并可以将其用作新查询的input。 我个人通常喜欢通过两个variables来做到这一点:
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
或者按照上面的例子将查询分成两部分的时候。 这不仅意味着查询的早期部分不应该被使用,而且简化了正在发生的事情 – 当然这意味着在每一步都有可能减less复制的次数。
另一方面,当你想保留其他的语境时, let
更有意义。
主要区别在于let
将variables注入上下文/作用域,其中into
创build新的上下文/作用域。
想知道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不完美,相同的string处理代码在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到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更聪明 ,string进程只执行一次。