Я предполагаю, что вы не хотите (по уважительной причине) сделать свой класс критериев, например,
public class Criteria<T, U>
{
//some filter properties...
public Expression<Func<T, U>> OrderBy { get; set; }
}
, который должен работать ... так что вот пара альтернатив:
public class Criteria<T>
{
//some filter properties...
public Expression OrderBy { get; set; }
public void CreateOrdering<U>(Expression<Func<T, U>> value)
{
OrderBy = value;
}
}
, но так как OrderBy больше не является типизированным типом, вам нужно изменить код, который его применяет:
var orderBy = Expression.Call(
typeof(Queryable),
"OrderBy",
new Type[] { query.ElementType, query.ElementType },
query.Expression,
criteria.OrderBy);
var sortedQuery = query.Provider.CreateQuery<T>(orderBy
, альтернативно, вы можете обработать это в коде, который впоследствии применяет порядок:
вместо
var sortedQuery = query.OrderBy(criteria.OrderBy);
сделать что-то вроде (не проверял это, но должно быть в основном так) (ОБНОВЛЕНИЕ: у этого нет никаких предварительных предположений, что вы используетедженерики).
// grab the property expression out of your ordering statement
var expressionProperty = criteria.OrderBy.Body is UnaryExpression ? (MemberExpression)((UnaryExpression)criteria.OrderBy.Body).Operand : (MemberExpression)criteria.OrderBy.Body;
// recreate the lambda as Expression<Func<T,U>> where T is the queryable element type and U
// is the actual type of the property, not an object
var orderBy = Expression.Lambda(expressionProperty, criteria.OrderBy.Parameters.Single());
// apply new lambda instead
var sortedQuery = query.OrderBy(orderBy);