Я в настоящее время отрабатывает на 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;
Как noVowel
и n
переменные доступны для использования (хотя я не использовал его в данном случае).
Хотя я вижу разницу, я не совсем понимаю, почему нужно использовать into
ключевое let
слово вместо ключевого слова, если только кто-то явно не хочет убедиться, что предыдущие переменные не могут использоваться в последних частях запроса.
Итак, есть ли веская причина, по которой существуют оба ключевых слова?
let
примере -where noVowel
чтоnoVowel
в этом случае?Ответы:
Да, потому что, как вы сказали, они делают разные вещи.
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
вводится в контекст / область видимости, где создается новый контекст / область видимости.источник
Желая узнать разницу на стороне БД, написал 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 не идеален, один и тот же строковый код процесса повторяется в двух местах (где и выберите).
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
Вот SQL, созданный 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
Кажется, Linq-to-SQL умнее Entity Framework, строковый процесс выполняется только один раз.
источник
Визуализированная версия ответа леппи . Как видно, компилятор выдает ошибку в запросе, в
into
отличие от последнего, как доступ к первой переменной.источник