Поддерживает ли LINQ-to-SQL составные запросы?

Как программист, не разбирающийся в C#, мне любопытна семантика оценки таких запросов LINQ:

var people = from p in Person
             where p.age < 18
             select p

var otherPeople = from p in people
                  where p.firstName equals "Daniel"
                  select p

Предполагая, что Person является объектом ADO, который определяет поля age и firstName, что это будет делать с точки зрения базы данных? В частности, будет ли выполняться запрос people для создания структуры в памяти, которая затем будет запрашиваться запросом otherPeople? Или создание otherPeople будет просто извлекать данные, относящиеся к запросу, из people, а затем создавать новый одноранговый запрос к базе данных? Итак, если я повторю оба этих запроса, сколько операторов SQL будет выполнено?

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
5
0
1 129
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

people и otherPeople содержат объекты типа IQueryable<Person>.

Если выполнить итерацию по обоим по отдельности, будет выполнено два запроса. Если вы выполняете итерацию только по otherPeople, он выполнит ожидаемый запрос с двумя предложениями where.

Если вы выполняете .ToList() на people и используете возвращенный List<Person> во втором запросе вместо людей, он становится LINQ-to-Objects, и SQL не выполняется.

Такое поведение называется отложенным выполнением. Это означает, что запросы не выполняются, пока они не понадобятся. Перед выполнением они представляют собой просто деревья выражений, которыми манипулируют для формулирования окончательного запроса.

Оба этих запроса будут выполнены, когда вы попытаетесь получить доступ к окончательным результатам. Вы можете попробовать просмотреть исходный SQL, созданный из свойств объекта DataContext.

Ответ принят как подходящий

Их можно компоновать. Это возможно, потому что запросы LINQ на самом деле являются выражениями (кодом как данными), которые поставщики LINQ, такие как LINQ-to-SQL, могут оценивать и генерировать соответствующий SQL.

Поскольку запросы LINQ обрабатываются лениво (например, не будут выполняться, пока вы не выполните итерацию по элементам), показанный вами код фактически не коснется базы данных. SQL будет сгенерирован и выполнен только после того, как вы переберете других людей или людей.

Да, итоговый запрос составлен. Он включает полное предложение where. Включите профилирование SQL и убедитесь в этом сами.

Linq делает это с помощью деревьев выражений. Первый оператор linq создает дерево выражений; он не выполняет запрос. Второй оператор linq строится на дереве выражения, созданном первым. Оператор выполняется только тогда, когда вы перечисляете результирующую коллекцию.

var people = from p in Person
             where p.age < 18
             select p

Переводит на:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0]
WHERE [t0].[Age] < @p0

где @ p0 передается как 18

var otherPeople = from p in people
                  where p.firstName equals "Daniel"
                  select p

Переводит на:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0]
WHERE [t0].[FirstName] = @p0

где @ p0 передается как "Даниэль"

var morePeople = from p1 in people
                 from p2 in otherPeople
                 where p1.PersonId == p2.PersonId
                 select p1;

Переводит на:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0], [dbo].[Person] AS [t1]
WHERE ([t0].[PersonId] = [t1].[PersonId]) AND ([t0].[Age] < @p0) AND ([t1].[FirstName] = @p1)

где @ p0 - 18, @ p1 - "Daniel"

В случае сомнений вызовите ToString () в своем IQueryable или дайте TextWriter свойству Log DataContext.

Другие вопросы по теме