簡體   English   中英

為動態對象創建linq表達式樹

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM