[英]LINQ to Entities OrderBy Expression Tree
我正在嘗試編寫一個LINQ查詢來orderBy由字符串值給出的動態屬性。
這是我的原始代碼:
Expression<Func<T, dynamic>> orderBy = i => i.GetType().GetProperty("PropertyName").GetValue(null);
當我試圖運行此命令時,我得到以下異常:
LINQ to Entities無法識別方法'System.Object GetValue(System.Object)'方法,並且此方法無法轉換為存儲表達式。
我試圖通過創建一個表達樹來解決這個問題,該表達式將給出相同的結果。 代碼應該能夠返回任何類型,具體取決於參數,但我遇到了返回類型的問題。 如果我沒有轉換值,我會得到一個不同的錯誤,說無法將Nullable DateTime轉換為Object。 這是我到目前為止的代碼:
ParameterExpression pe = Expression.Parameter(typeof(T), "s");
Expression<Func<T, dynamic>> orderByExpression = Expression.Lambda<Func<T, dynamic>>(Expression.Convert(Expression.Property(pe, "PropertyName"), typeof(object)), pe);
和我的新例外:
無法將類型'System.Nullable`1 [[System.DateTime]]'強制轉換為'System.Object'類型。 LINQ to Entities僅支持轉換EDM原語或枚舉類型。
如何編寫此表達式樹以返回動態類型? 還有一種更好的方法我應該在LINQ中這樣做嗎?
Expression<Func<T, TT>>
沒有模板參數,它允許您表示引用類型和值類型。 當然,您可以構建表達式,但必須通過反射與它們進行交互。
這將正確排序集合:
IOrderedEnumerable<TEntityType> SortMeDynamically<TEntityType>(IEnumerable<TEntityType> query, string propertyname)
{
var param = Expression.Parameter(typeof(TEntityType), "s");
var prop = Expression.PropertyOrField(param, propertyname);
var sortLambda = Expression.Lambda(prop, param);
Expression<Func<IOrderedEnumerable<TEntityType>>> sortMethod = (() => query.OrderBy<TEntityType, object>(k => null));
var methodCallExpression = (sortMethod.Body as MethodCallExpression);
if (methodCallExpression == null)
throw new Exception("Oops");
var method = methodCallExpression.Method.GetGenericMethodDefinition();
var genericSortMethod = method.MakeGenericMethod(typeof(TEntityType), prop.Type);
var orderedQuery = (IOrderedEnumerable<TEntityType>)genericSortMethod.Invoke(query, new object[] { query, sortLambda.Compile() });
return orderedQuery;
}
或者,如果你想在IQueryable
上使用它(例如,如果你使用的是EF)
IOrderedQueryable<TEntityType> SortMeDynamically<TEntityType>(IQueryable<TEntityType> query, string propertyname)
{
var param = Expression.Parameter(typeof(TEntityType), "s");
var prop = Expression.PropertyOrField(param, propertyname);
var sortLambda = Expression.Lambda(prop, param);
Expression<Func<IOrderedQueryable<TEntityType>>> sortMethod = (() => query.OrderBy<TEntityType, object>(k => null));
var methodCallExpression = (sortMethod.Body as MethodCallExpression);
if (methodCallExpression == null)
throw new Exception("Oops");
var method = methodCallExpression.Method.GetGenericMethodDefinition();
var genericSortMethod = method.MakeGenericMethod(typeof(TEntityType), prop.Type);
var orderedQuery = (IOrderedQueryable<TEntityType>)genericSortMethod.Invoke(query, new object[] { query, sortLambda });
return orderedQuery;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.