Почему платформа Entity генерирует этот SQL? - PullRequest
12 голосов
/ 26 мая 2011

У меня есть этот оператор LINQ,

var carriageways = from carriageway in dataModelCurrentEntities.Carriageway
                   where carriageway.RoadId == roadId && carriageway.DistanceBreak == false
                   orderby carriageway.CarriagewayStartInMetre
                   select new CarriagewaySummary
                   {
                       StartMetres = carriageway.CarriagewayStartInMetre, 
                       EndMetres = carriageway.CarriagewayEndInMetre
                   };

Он генерирует SQL в этой форме (LINQ для сущностей),

SELECT 
Project1.field1 AS field1
Project1.field2 AS field2
FROM ( SELECT 
    Extent1.field1 AS field1, 
    Extent1.field2 AS field2
    FROM table AS Extent1
    WHERE blah
)  AS Project1
ORDER BY blah ASC

В чем причина этого?Я бы подумал, что этого достаточно,

SELECT 
fields
FROM table as Project1
WHERE blah
ORDER BY blah ASC

Напоминаю, что LINQ to SQL будет генерировать более простой SQL.

Я рассмотрел более сложные примеры с объединениями и т. Д.,и LINQ для сущностей, кажется, генерирует более сложный SQL.

ОБНОВЛЕНИЕ:

Это довольно интересно, потому что я пытался проверить, что вы говорите, и я столкнулсяэтот LINQ,

var attachments = (from a in entities.Attachments
                  where a.AttachmentID == 749
                  select new {a.AddedOn, a.AddedBy});

И который генерирует этот SQL,

SELECT 
[Extent1].[AttachmentID] AS [AttachmentID], 
[Extent1].[AddedOn] AS [AddedOn], 
[Extent1].[AddedBy] AS [AddedBy]
FROM [dbo].[Attachment] AS [Extent1]
WHERE 749 = [Extent1].[AttachmentID]

У этого нет подзапроса.

Разница в том, что хорошоиз них хотя бы) ... жди.Informix.Первый запрос выше, который генерирует подзапрос, использует informix.Второй запрос, который не является сервером SQL.

Это может быть не так просто, потому что запросы различаются.

Я взял второй запрос и разбил его на подпрограмму.запрос, подобный этому (вручную),

SELECT 
[Project1].[AttachmentID] AS [AttachmentID], 
[Project1].[AddedOn] AS [AddedOn], 
[Project1].[AddedBy] AS [AddedBy]

    FROM ( SELECT

    [Extent1].[AttachmentID] AS [AttachmentID], 
    [Extent1].[AddedOn] AS [AddedOn], 
    [Extent1].[AddedBy] AS [AddedBy]
    FROM [dbo].[Attachment] AS [Extent1]
    WHERE 749 = [Extent1].[AttachmentID]
    ) AS Project1

SQL-сервер показывает один и тот же план выполнения для обоих, так что, как вы говорите, SQL-сервер может довольно хорошо его оптимизировать.Informix, с другой стороны, не умеет оптимизировать вещи.

1 Ответ

7 голосов
/ 26 мая 2011

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

В данной проекции в OP имеет смысл генерировать подзапрос.Он запрашивает набор значений (new ... {StartMetres, EndMetres}), которые взяты из предыдущего «запроса».Генерация запроса, таким образом, выдаст "SELECT <requested values> FROM something", где "something" будет отображаться как запрос.Таким образом, простое посещение дерева запросов приводит к подзапросу.

Как только этот процесс будет завершен, поставщик, безусловно, сможет "оптимизировать" полученный SQL-запрос и удалить подзапрос.Тем не менее, именно в таких вещах механизмы SQL-запросов действительно хороши, поэтому имеет смысл делегировать эту задачу механизму запросов.Возможно, это зависит от базы данных, которую вы используете, но вполне вероятно, что план запроса для оператора SQL с подзапросом будет идентичен «оптимизированному» без подзапроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...