Применительно к платформе сущностей методы расширения Select()
и OrderBy()
оба возвращают ObjectQuery
, который определяется как:
public class ObjectQuery<T> : ObjectQuery, IOrderedQueryable<T>,
IQueryable<T>, <... more interfaces>
Тип возврата Select()
равен IQueryable<T>
, а тип OrderBy
равен IOrderedQueryable<T>
. Таким образом, вы можете сказать, что оба возвращают один и тот же тип, но в другой оболочке. К счастью, потому что теперь мы можем применить ThenBy
после вызова OrderBy
.
Теперь моя проблема.
Допустим, у меня есть это:
var query = context.Plots.Where(p => p.TrialId == 21);
Это дает мне IQueryable<Plot>
, то есть ObjectQuery<Plot>
. Но это также IOrderedQueryable:
var b = query is IOrderedQueryable<Plot>; // True!
Но все же:
var query2 = query.ThenBy(p => p.Number); // Does not compile.
// 'IQueryable<Plot>' does not contain a definition for 'ThenBy'
// and no extension method 'ThenBy' ....
Когда я делаю:
var query2 = ((IOrderedQueryable<Plot>)query).ThenBy(p => p.Number);
Компилируется, но выдает исключение времени выполнения:
Выражение типа 'IQueryable`1[Plot]
' нельзя использовать для параметра типа 'IOrderedQueryable`1[Plot]
'метода' IOrderedQueryable`1[Plot] ThenBy[Plot,Nullable`1](IOrderedQueryable`1[Plot], Expressions.Expression`1[System.Func`2[Plot,System.Nullable`1[System.Int32]]])
'
Приведение выполняется (я проверил), но параметр ThenBy
по-прежнему рассматривается как IQueryable (что меня немного озадачивает).
Теперь предположим, что какой-то метод возвращает мне ObjectQuery<Plot>
как IQueryable<Plot>
(например, Select()
). Что делать, если я хочу знать, безопасно ли вызывать ThenBy
для возвращенного объекта. Как я могу понять это, если ObjectQuery
является "реальным" или "фальшивым" IOrderedQueryable
без ловли исключений?