#linq #linq-to-objects #dynamic-linq
#linq #linq-to-objects #динамический-linq
Вопрос:
У меня был следующий запрос с использованием обычного linq, и он отлично работал (с использованием анонимного типа),
var result = from s in Items
group s by s.StartTime into groupedItems
select new {groupedItems.Key, Items= groupedItems.OrderBy(x => x.Name) };
Но с помощью динамического Linq я не могу упорядочить его внутри groupby.
result = Items.GroupBy("StartTime", "it").OrderBy("Name");
В нем указано, что имя недоступно. Стоит отметить, что если я отключу свой порядок, все будет отлично работать, но элементы внутри каждого «ключа» не упорядочиваются.
Ответ №1:
Это хороший вопрос!
Я смоделировал вашу ситуацию, создав класс с именем Item .
public class Item
{
public DateTime StartTime { get; set; }
public string Name { get; set; }
}
а затем создал базовый список элементов для выполнения groupby.
List<Item> Items = new List<Item>()
{
new Item() { StartTime = DateTime.Today, Name = "item2"},
new Item() { StartTime = DateTime.Today, Name = "item1"},
new Item() { StartTime = DateTime.Today.AddDays(-1), Name = "item3"},
};
Теперь большая разница в 2 запросах заключается в том, где выполняется order by . В первом запросе, когда вы выполняете groupedItems.OrderBy(x => x.Name)
его, он выполняется для IGrouping<DateTime,Item>
или для одной записи, поскольку он перебирает все группировки.
Во втором запросе порядок выполняется постфактум. Это означает, что вы выполняете упорядочивание на a IEnumerable<IGrouping<DateTime,Item>>
, потому что итерации уже произошли.
Поскольку Microsoft была хороша, они добавили кое-что, чтобы помочь справиться с этим для выражений. Эта перегрузка позволяет указать элемент, возвращаемый при итерации по коллекции. Вот пример кода:
var expressionResult = Items.GroupBy(x => x.StartTime,
(key, grpItems) => new { key, Items = grpItems.OrderBy(y => y.Name) });
Во второй части GroupBy вы можете указать лямбда-выражение, которое принимает ключ и группировку элементов по этому ключу и возвращает указанную вами запись, которая такая же, как и в исходном запросе.
Надеюсь, это поможет!