Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert IQueryable to IOrderedQueryable

Tags:

c#

join

linq

I have 2 tables : Items and ItemMetrics. Items contains my items and ItemMetrics contains statistics about those items.

I'm trying to sort a list of Items by the corresponding statistic Weight. I got it to work using a subquery, but I thought it was a little inefficent and could be optimized...

items.OrderBy(item => (from metric in Context.ItemMetrics where item.ItemId == metric.ItemId select metric.Weight).FirstOrDefault());

...So I am trying to accomplish the same thing using a join...

from item in items join metric in ItemMetrics on item.ItemId equals metric.ItemId orderby metric.Weight select item;

This is working fine in LINQPad. I need to return an IOrderedQueryable for a supplmentary method to do some paging using Skip and Take, but the compiler is telling me the result of this query is an IQueryable.

The only way I can think of explictly implying IOrderedQueryable is wrapping the query in

OrderBy(x => 0)

Is there a better way?

like image 281
David James Ball Avatar asked Aug 27 '26 18:08

David James Ball


1 Answers

The problem is that an IOrderedQueryable needs to be able to apply a secondary ordering - and by the time you've projected the item/metric pair to just an item, you've lost the primary ordering.

One approach would be to defer the projection until later:

var ordered = items.Join(ItemMetrics,
                         item => item.ItemId,
                         metric => metric.ItemId,
                         (item, metric) => new { item, metric })
                   .OrderBy(pair => pair.Metric.Weight);
var paged = ApplyPaging(ordered, pageConfiguration); // Whatever
var query = paged.Select(pair => pair.Item);

That's assuming ApplyPaging (or whatever you're using) returns an IQueryable or an IOrderedQueryable.

like image 130
Jon Skeet Avatar answered Aug 30 '26 09:08

Jon Skeet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!