2011-12-27 2 views
4

У меня есть Действие модель с сессии Navigation собственности,Почему Linq GroupBy После того, как OrderBy отклонил операцию заказа?

Рассмотрим этот код:

var x=db.Actions.OrderBy(p => p.Session.Number).ThenBy(p => p.Date);//it's OK 

х представляет собой упорядоченный действие, но когда сгруппированы по х, группа не перебирать на х (базовый на Action.Session) вручную на упорядоченном перечислимы:

var y=x.GroupBy(p=>p.Session).ToArray() 

у ВГА e группа (Key, IGrouping) сессий, но почему group.Key не заказано база на Session.Number?

Как достичь группы по порядку по порядку и каждой группе по дате?

ответ

3

Потому что это Enumerable.GroupBy, который сохраняет заказ. Такое обещание не сделано для Queryable.GroupBy. Из документации бывший:

IGrouping (Of ​​TKey, TElement) объекты уступила в порядке, основанном на порядка элементов в источнике, которые произвели первый ключ каждого IGrouping (Of ​​TKey, TElement). Элементы в группировке даются в порядке , они появляются в источнике.

Вы называете последнее, и выше не упоминается. Позвоните OrderBy после GroupBy, чтобы заставить его работать.

Update: так как вы, очевидно, хотите, чтобы отсортировать на более, чем просто ключ GroupBy, вы должны быть в состоянии использовать другой GroupBy перегружать, чтобы указать, что список каждой сессии действий должен быть отсортирован:

db.Actions.GroupBy(
    p => p.Session, 
    (session, actions) => new { 
     Session = session, 
     Actions = actions.OrderBy(p => p.Date) 
    }).OrderBy(p => p.Session.Number).ToArray(); 
+0

спасибо, я редактирую свой вопрос. –

+0

@RedHat Я обновил ответ, но, к сожалению, я не могу проверить, что это поддерживается провайдером прямо сейчас. Вы можете попробовать это, или я попробую его и при необходимости обновить ответ, когда я получу шанс. – hvd

+0

спасибо @hvd за вашу заметку, ваш ответ хорош, но я не нахожу перегрузку метода GroupBy, который принимает (сеанс, действия) => ..., также я отвечаю на вопрос ниже. –

2

Поскольку это не определено, что GroupBy сохраняет любой порядок вставки или основной ключевой заказ (таким же образом, что Dictionay<,> не дает такой гарантии, для локальной работы в оперативной памяти). Только заказ после группировки, вместо:

var y = db.Actions.GroupBy(p=>p.Session).OrderBy(grp => grp.Key).ToArray(); 

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

+0

Спасибо за Ваше сообщение, я хочу, чтобы отсортировать групповой ключевой базы на Session.Number и каждой группе, отсортированной по Action.Date, как это сделать? Я редактирую свой вопрос. –

+0

@RedHat для этого вы могли бы * попробовать * поместить OrderBy (x => x.Date) в первую строку, где Number был –

0

Просто имя GroupBy предполагает, что запрошенные данные в этот момент будут сгруппированы, агрегированы (вызовите, как вы хотите) в другой блок данных на основе предоставленного параметра.

В общем, если вы хотите увидеть результат sortedSort() вызов функции должен быть последним в последовательности.

+0

спасибо, я редактирую свой вопрос. –

0

Благодаря @Marc Gravell & @hvd для заметки о groupby IGrouping (Of ​​TKey, TElement) не сохраняет порядок TKey, но сохраняет порядок TElement.

Так что мой ответ на мой последний вопрос (Как я достиг группу порядка сессии по номеру и каждой группе упорядоченный по дате?) является:

var x= db.Actions 
.OrderBy(p => p.ActionDateTime) 
.GroupBy(p => p.Session) 
.OrderBy(q => q.Key.Number) 
.ToArray(); 
Смежные вопросы