visual tutorial sintaxis programación framework español ejemplos consultas consulta con anidadas c# linq

c# - tutorial - ¿La palabra clave let de linq es mejor que su palabra clave?



sintaxis linq c# (3)

La principal diferencia es que let inyecta la variable en el contexto / scope, donde into crea un nuevo contexto / scope.

Actualmente estoy revisando LINQ y estoy tratando de comprender la diferencia entre let y usar la palabra clave into . Hasta ahora, la palabra clave let parece mejor que la palabra clave into en lo que a mí respecta.

La palabra clave into esencia le permite a uno continuar una consulta después de una proyección. (Solo quiero indicar explícitamente que no me estoy refiriendo a la unión grupal).

Dada una variedad de nombres, permite hacer lo siguiente:

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

Toma el resultado de la selección y lo coloca en la variable noVowel que luego permite introducir cláusulas where , orderby y select adicionales. Una vez que se noVowel variable noVowel , la variable n ya no está disponible.

La palabra clave let , por otro lado, usa tipos temporales anónimos para permitirle reutilizar más de una variable a la vez.

Puedes hacer lo siguiente:

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

Las variables noVowel n están disponibles para su uso (aunque no lo he usado en este caso).

Si bien puedo ver la diferencia, no puedo entender por qué uno querría usar la palabra clave into en lugar de la palabra clave let menos que uno explícitamente quisiera asegurarse de que las variables anteriores no puedan ser utilizadas en las últimas partes de la consulta.

Entonces, ¿hay una buena razón por la cual ambas palabras clave existen?


Queriendo saber la diferencia en el lado de la base de datos, escribió 2 consultas de Entity Framework.

  • Dejar

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

  • Dentro

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

Los SQL generados son casi idénticos . El SQL no es perfecto, el mismo código de proceso de cadena se repite en 2 lugares (donde y seleccione).

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

Aquí está el SQL generado por 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

Parece que Linq-to-SQL es más inteligente que Entity Framework, el proceso de cadena se realiza solo una vez.


Sí, porque están haciendo cosas diferentes, como dices.

select ... into in aísla efectivamente la totalidad de una consulta y le permite usarla como entrada para una nueva consulta. Personalmente, generalmente prefiero hacer esto a través de dos variables:

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

(Es cierto que en este caso lo haría con notación de puntos en dos líneas, pero ignorando eso ...)

A menudo no quiere todo el equipaje de la parte anterior de la consulta, que es cuando usa select ... into o dividir la consulta en dos como se muestra en el ejemplo anterior. Esto no solo significa que las partes anteriores de la consulta no se pueden usar cuando no deberían, sino que simplifica lo que está sucediendo, y por supuesto significa que hay potencialmente menos copias en cada paso.

Por otro lado, cuando quieras mantener el resto del contexto, let tenga más sentido.