Последовательность метода LINQ какой-либо важности? - PullRequest
11 голосов
/ 16 декабря 2010

Просто интересно, имеет ли значение, в какой последовательности добавляются методы LINQ?

Например.

using(MyDataContext context = new MyDataContext())
{
   var user = context.Users
                     .Where(u => u.UserName.StartsWith("t"))
                     .OrderByDescending(u => u.CreatedDate)
                     .FirstOrDefault();
}

а это полностью то же самое?

using(MyDataContext context = new MyDataContext())
{
   var user = context.Users
                     .OrderByDescending(u => u.CreatedDate)
                     .Where(u => u.UserName.StartsWith("t"))
                     .FirstOrDefault();
}

Конечно, я могу протестировать все методы один за другим, но мне хотелось бы иметь общее представление о логике.

Итак:

  • Кроме методов, таких как FirstOrDefault (), ToList () и других методов, которые действительно запускают выполнение, имеет ли какое-либо значение иметь какой-либо порядок в выражении LINQ?

Еще раз спасибо!

Ответы [ 7 ]

10 голосов
/ 16 декабря 2010

В LINQ to SQL я бы ожидал, что эти два запроса будут одинаковыми - по крайней мере, они должны иметь один и тот же план запросов, даже если не точно такой же SQL.

В LINQ toОбъекты, они будут вести себя совсем по-другому.Представьте, что у вас был миллион пользователей, но только у двух из них были имена пользователей, начинающиеся с "t".в первой форме вы будете фильтровать, а затем сортировать этих двух пользователей ... во второй форме нужно будет отсортировать все до начала фильтрации.

Конечно, естьв других ситуациях порядок также имеет значение - в частности, если у вас есть Select на полпути вниз, а затем предложение Where, вы будете фильтровать разные вещи.Представьте себе:

var query = Enumerable.Range(-20, 30)
                      .Select(x => -x)
                      .Where(x => x > 5);

против

var query = Enumerable.Range(-20, 30)
                      .Where(x => x > 5)
                      .Select(x => -x);

В первом примере результаты будут "20, 19, 18, ... 6", тогда как во втором запросе результаты будутбыть "-6, -7, -8, -9, -10".Сильно отличается!

4 голосов
/ 16 декабря 2010

Это зависит от того, какого поставщика LINQ вы используете.В случае LINQ to SQL дерево выражений будет анализироваться на один и тот же базовый запрос SQL в любом случае.Однако с менее интеллектуальным провайдером вы можете обнаружить, что выполнение сначала .Where() было бы более эффективным, так как оно отфильтровывало бы ваши объекты перед их сортировкой, что могло бы иметь большое значение для большого числа объектов.

1 голос
/ 16 декабря 2010

Я думаю, что речь идет о провайдере LINQ to XXXX. Кто написал провайдеру, может сказать, что он может сделать (об оптимизации и т. Д.). Даже возможно дать другие результаты (только в переводах) в другой версии того же поставщика LINQ.

Одним словом, поставщики LINQ - это просто переводчики, поэтому вам следует задать этот вопрос создателю поставщика LINQ, которым вы сейчас пользуетесь.

1 голос
/ 16 декабря 2010

Как насчет использования Sql Profiler? Это даст правильный ответ.

1 голос
/ 16 декабря 2010

В общем, да, это имеет значение. Вы можете получить различную производительность и / или разные результаты.

В вашем конкретном примере порядок не изменит результат. Для большинства провайдеров, таких как LINQ to SQL и LINQ to Entities, это также не будет иметь никакого значения - будет генерироваться один и тот же SQL.

Для других поставщиков другой порядок может изменить характеристики производительности, но то, как это произойдет, зависит от конкретного поставщика. Например, я не думаю, что LINQ to Objects будет иметь одинаковую производительность для обоих запросов.

1 голос
/ 16 декабря 2010

Я не уверен на 100%, но я думаю, что второй медленнее, поскольку вы выполняете сортировку по большому набору данных.Если вы сначала отфильтруете, то удалите некоторые элементы, что ускорит сортировку.Однако результат должен быть таким же.

РЕДАКТИРОВАТЬ: Так как это выглядит как linq-to-sql (если вы не используете другого поставщика linq), он должен сводиться к тому жезапрос выполняется в этом примере.Но бывают ситуации, когда порядок имеет значение и в linq-to-sql (см. Пример Джона).Тем не менее, единственный способ быть на 100% уверенным - это использовать профилировщик для исследования сгенерированного SQL-запроса (но в этом примере я не думаю, что есть какая-либо разница).

0 голосов
/ 16 декабря 2010

Возможны проблемы с производительностью.В вашем случае первый пример будет наилучшим, потому что на втором вы сначала сортируете весь список перед фильтрацией.Вы даже сортируете все, что вам не нужно, а затем удаляете ненужные части.Сначала вы удаляете все, что вам не нужно, затем вы сортируете подмножество, которое (вероятно) будет намного меньше.

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

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