Reputation: 913
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?
Upvotes: 3
Views: 4262
Reputation: 1502286
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
.
Upvotes: 5