Порядок преобразования linq в sql

Я использую следующий синтаксис запроса

from table
where 
where
orderby 
orderby

Где first orderby - это дата, а second orderby - это дата. Я бы предположил, что это будет работать как orderby thenby, но, похоже, делает что-то еще.

  1. Как я могу сделать заказ, используя указанный выше синтаксис без использования синтаксиса расширения. (Понятно)

  2. А что делает orderby, orderby?


person Curtis White    schedule 25.05.2010    source источник


Ответы (4)


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

Используйте запятую между полями:

orderby a, b

А что делает orderby, orderby?

Когда вы используете orderby два раза подряд, элементы концептуально сначала сортируются с использованием первого orderby, а затем снова сортируются с использованием второго orderby. Поскольку сортировка определена как стабильная сортировка (объекты, связанные со вторым orderby останется в том же порядке, что и после сортировки с первым orderby, это фактически означает, что это:

var query = from x in l
            orderby x.A
            orderby x.B
            select x;

эквивалентно:

var query = from x in l
            orderby x.B, x.A
            select x;

В результате orderby термины поменялись местами с того, что вы, вероятно, планировали.

Тестирование с помощью LINQ to SQL

Это можно проверить, попробовав в LINQ to SQL. Я создал следующий запрос:

var query = from a in dc.Orders
            orderby a.Date
            orderby a.CustomerID
            select a;

и это был сгенерированный SQL:

SELECT [t0].[ID], [t0].[CustomerID], [t0].[Date], [t0].[Description]
FROM [dbo].[Order] AS [t0]
ORDER BY [t0].[CustomerID], [t0].[Date]

Обратите внимание, что orderby a.Date не игнорируется. Оба термина включены в предложение ORDER BY, но в обратном порядке, чем вы могли предполагать.

person Mark Byers    schedule 25.05.2010
comment
Согласно спецификации OrderBy всегда является стабильной сортировкой (независимо от поставщика LINQ). Это означает, что если ключи двух элементов равны, порядок элементов сохраняется. Будет ли в цепочке OrderBy сохранять порядок, зависит от используемых ключей, а не от поставщика LINQ (хотя это, очевидно, повлияет на значения ключей). - person hemp; 26.05.2010
comment
@hemp: Я думаю, вы правы, после того, как изучили его подробнее. Как ни странно, ваш собственный ответ, в котором вы цитируете MSDN (Doing this introduces a new primary ordering that ignores the previously established ordering.), противоречит тому, что вы только что сказали в этом комментарии. Но я думаю, что это неправильный MSDN. - person Mark Byers; 26.05.2010
comment
Это прямо не противоречит, это просто сбивает с толку. Он говорит о том, что существующий порядок не будет учтен новым первичным порядком. Однако после применения первоначального упорядочивания, если новое упорядочение обнаружит, что значения ключей равны, оно не изменит порядок этих элементов. Так что на самом деле оба утверждения верны, но не очень ясны. - person hemp; 26.05.2010
comment
@hemp: Хорошо, я думаю, теперь я это понимаю. Я должен согласиться с вами, что это сбивает с толку. :) Я тестировал его как с LINQ to Objects, так и с LINQ to SQL, и сортировка стабильна в обоих случаях. Должен сказать, я был немного удивлен, что SQL был именно таким, каким должен быть - один ORDER BY с перевернутыми условиями. Кто-то там хорошо поработал! - person Mark Byers; 26.05.2010

Выполнить ThenBy в синтаксисе выражения запроса несложно, просто следуйте начальному порядкуby с запятой и вторым утверждением:

// Create the data source.
List<Student> students = GetStudents();

// Create the query.
IEnumerable<Student> sortedStudents =
    from student in students
    orderby student.Last ascending, student.First ascending
    select student;

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

На самом деле ответ на этот вопрос содержится непосредственно в документации MSDN для Enumerable.OrderBy и Enumerable.ThenBy методы.

Поскольку IOrderedEnumerable наследуется от IEnumerable, вы можете вызвать OrderBy или OrderByDescending по результатам вызова OrderBy, OrderByDescending, ThenBy или ThenByDescending. Это вводит новый первичный порядок, который игнорирует ранее установленный порядок.

person hemp    schedule 25.05.2010

Оператор ThenBy применяет к последовательности вторичный возрастающий порядок сортировки. Это похоже на применение вторичного порядка сортировки в T-SQL, например:

Select * from Customer order by FirstName,lastName

В linq это можно записать как:

var thenby = mode.CustList.Select(cus => new
        {
            cus. FirstName,
            cus. LastName,
            cus. EmailAddress
        }).OrderBy(cus => cus. FirstName).ThenBy(cus => cus. LastName);

Вы можете узнать об этом больше здесь: http://dotnetreaders.com/articles/ThenBy_in_LINQ_c-sharp,_Orderby_Thenby_in_LINQ_C-sharp/204

person sudhakar    schedule 13.07.2012

Ответ на этот вопрос должен быть таким

порядок по 1, 2

Я оставлю часть №2 кому-нибудь другому.

person Curtis White    schedule 25.05.2010