我正在尝试动态构建表达式树以进行排序。排序将在我的 Web api 的操作过滤器中进行。因此对象的类型在运行时之前都是未知的。
概述如下:
在操作过滤器级别:
IEnumerable<object> model = null;
context.Response.TryGetContentValue(out model);
model=model.OrderByExtension(orderByField, orderDirection);
context.Response.Content=new ObjectContent<IEnumerable<object>>(model, new JsonMediaTypeFormatter());
扩展方法:
public static IQueryable<T> OrderByExtension<T>(this IQueryable<T> source, string sortProperty, Sorting.SortingOption sortOrder)
{
var type = source.FirstOrDefault().GetType(); //Gets the type of object passed, since typeof(T) is only object at this point
var property = type.GetProperty(sortProperty);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
var typeArguments = new Type[] { typeof(T), property.PropertyType };
var methodName = sortOrder == Sorting.SortingOption.Asc ? "OrderBy" : "OrderByDescending";
var resultExp = Expression.Call(typeof(Queryable), methodName, typeArguments, source.Expression, Expression.Quote(orderByExp));
return source.Provider.CreateQuery<T>(resultExp);
}
在 Expression.Call - 我收到错误:“System.Linq.Queryable”类型上的泛型方法“OrderByDescending”与提供的类型参数和参数不兼容。
我假设调用 OrderBy 方法时,“对象”类型与实际类型不匹配。
有什么办法可以让它发挥作用吗?
提前致谢。 ps:我还尝试通过 .MakeGenericMethod 创建 OrderBy 的通用方法 - 但没有成功。
最佳答案
问题在于您生成的是实际基础类型的函数表达式,而不是源表达式的类型 (object
)。您需要在生成的表达式中添加对您的类型的转换。
public static IQueryable<object> OrderByExtension(this IQueryable<object> source, string sortProperty, SortOrder sortOrder = SortOrder.Unspecified)
{
var sourceType = typeof(object);
var underlyingType = source.First().GetType();
var propertyType = underlyingType.GetProperty(sortProperty).PropertyType;
var param = Expression.Parameter(sourceType);
var body = Expression.Property(
Expression.Convert(param, underlyingType), sortProperty
);
var lambda = Expression.Lambda(body, param);
var sortMethod = sortOrder == SortOrder.Descending ? "OrderByDescending" : "OrderBy";
var expr = Expression.Call(typeof(Queryable), sortMethod, new Type[] { sourceType, propertyType },
source.Expression, lambda
);
return source.Provider.CreateQuery<object>(expr);
}
关于c# - 为动态对象创建 linq 表达式树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37490834/