Le mot-clé letq de linq est-il meilleur que son mot-clé?

Je suis en train de rafraîchir LINQ et j’essaie de comprendre la différence entre le let et l’utilisation du mot-clé. Jusqu’à présent, le mot let clé let semble mieux que le mot-clé pour autant que je sache.

Le mot clé into permet essentiellement de continuer une requête après une projection. (Je veux juste dire explicitement que je ne parle pas de celui de la jointure de groupe.)

Étant donné un tableau de noms, il permet d’effectuer les opérations suivantes:

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

Il prend le résultat du select et le place dans la variable noVowel , ce qui permet d’introduire des clauses supplémentaires where , orderby et select . Une fois la variable noVowel créée, la variable n n’est plus disponible.

Le mot let clé let , quant à lui, utilise des types anonymes temporaires pour vous permettre de réutiliser plusieurs variables à la fois.

Vous pouvez effectuer les opérations suivantes:

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

Les variables noVowel et n sont disponibles pour l’utilisation (même si je ne l’ai pas utilisé dans ce cas).

Bien que je puisse voir la différence, je ne peux pas comprendre pourquoi on voudrait utiliser le mot-clé into sur le mot let clé let sauf si l’on veut explicitement que les variables précédentes ne peuvent pas être utilisées dans les dernières parties de la requête.

Y a-t-il une bonne raison pour laquelle les deux mots-clés existent?

Oui, parce qu’ils font des choses différentes, comme vous l’avez dit.

select ... into isole efficacement l’ensemble d’une requête et vous permet de l’utiliser comme entrée pour une nouvelle requête. Personnellement, je préfère généralement le faire via deux variables:

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

(Certes, dans ce cas, je le ferais avec une notation par points sur deux lignes, mais en ignorant cela …)

Souvent, vous ne voulez pas tout le bagage de la première partie de la requête – c’est-à-dire lorsque vous utilisez select ... into ou divisez la requête en deux selon l’exemple ci-dessus. Non seulement cela signifie-t-il que les parties les plus anciennes de la requête ne peuvent pas être utilisées alors qu’elles ne devraient pas être, cela simplifie ce qui se passe – et bien sûr cela signifie qu’il ya potentiellement moins de copies à chaque étape.

D’un autre côté, quand vous voulez garder le rest du contexte, let plus de sens.

La principale différence est que le let injecte la variable dans le contexte / la scope, où crée un nouveau contexte / champ.

Vouloir connaître la différence du côté de la firebase database, écrit 2 requêtes Entity Framework.

  • Laisser

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

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

Les SQL générés sont presque identiques . Le SQL n’est pas parfait, le même code de processus de chaîne est répété à 2 endroits (où et sélectionnez).

 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 

Voici le SQL généré par 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 

Il semble que Linq-to-SQL soit plus intelligent que Entity Framework, le processus de chaîne effectué une seule fois.