2010-08-12 1 views
3

Я использую .NET 4 и Entity Framework для создания простого запроса. Вот C# код:Почему LINQ to Entities делает подзапрос для меня?

return Context.Files.Where(f => f.FileHash != 40) 
        .OrderByDescending(f => f.Created) 
        .Take(5); 

Когда я проследить запрос с использованием ObjectQuery.ToTraceString(), я найти следующий подзапрос:

SELECT TOP (5) 
    [Project1].[ID] AS [ID], 
    -- <snip> lots of columns 
    [Project1].[FileHash] AS [FileHash] 
FROM (SELECT 
     [Extent1].[ID] AS [ID], 
     -- <snip> lots of columns 
     [Extent1].[FileHash] AS [FileHash] 
     FROM [dbo].[Files] AS [Extent1] 
     WHERE (LEN([Extent1].[FileHash])) <> 40 
) AS [Project1] 
ORDER BY [Project1].[Created] DESC 

FileHash определяется как NVARCHAR (255).

Это кажется странным для меня, поскольку я не вижу необходимости в подзапросе. Почему EF делает это для меня, и есть ли что-то, что я могу сделать, чтобы не взять то, что я предполагаю, - это удар производительности из такого запроса?

+1

Почему вы предполагаете, что это удар по производительности, а не усиление производительности (т. Е. Вы его измеряли/смотрели на план запроса)? – nos

+0

Что вы получаете без '.Take (5)'? –

+0

@nos: чистый предположение с моей стороны. Наверное, мне больше любопытно, насколько неуверенность в результате имеет строгая производительность. – ladenedge

ответ

3

Прежде всего, я сомневаюсь, что это стоит беспокоиться. Я предполагаю, что если вы сравните план выполнения запроса с тем, что генерирует EF для «оптимального» ручного запроса, результаты будут фактически одинаковыми. Я предполагаю, что единственным вероятным штрафом является то, что сгенерированный запрос EF занимает дольше секунды для синтаксического анализа. В великой схеме вещей это, вероятно, не стоит рассматривать.

Что касается того, почему EF генерирует запрос таким образом, в первую очередь, я уверен, что он связан с присущей сложностью перевода методов LINQ в действительные SQL-запросы. Я уверен, что движок, который выполняет этот перевод, очень модульный, и каждый модуль должен генерировать часть запроса, которая может быть легко включена в окончательный, полный запрос. Хотя, конечно, можно было бы запустить окончательный «оптимизационный» проход для устранения избыточности, вероятно, очень мало вреда для делегирования этой задачи самому SQL Server.

+0

Справедливо, я могу жить с этим. Спасибо за ваши мысли! – ladenedge

 Смежные вопросы

  • Нет связанных вопросов^_^