[英]Creating linq expression trees for dynamic objects
我正在嘗試動態構建表達式樹以進行排序。 排序將在我的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方法時,類型'object'和實際類型之間存在不匹配。
反正有沒有讓這個工作?
提前致謝。 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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.