在linq查询中设置动态排序名称字段
问题描述:
我希望能够使用lambda表达式获得OrderBy
查询,以便使用TOP(n)关键字(大性能提升)获得SQL查询。在linq查询中设置动态排序名称字段
我可以,如果我specifiy做到这一点...
PaginatedList = query.OrderBy(x => x.QuoteID).Skip(() => skipValue).Take(() => pageSize)
但因为我想要的排序依据字段设置为通过名字的UI选择我想要做这样的事情的动态:
var propertyInfo = typeof(Data.Quote).GetProperty(sortName);
Expression<Func<Data.Quote, object>> orderField = x => propertyInfo.GetValue(x, null);
PaginatedList = query.OrderBy(orderField).Skip(() => skipValue).Take(() => pageSize)
这给我的错误:
"LINQ to Entities does not recognize the method 'System.Object GetValue(System.Object)' method, and this method cannot be translated into a store expression."
这个我试过那是类型的不
var propertyInfo = typeof(Data.Quote).GetProperty(sortName);
Func<Data.Quote, object> orderField = x => propertyInfo.GetValue(x, null);
PaginatedList = query.OrderBy(x => orderField).Skip(() => skipValue).Take(() => pageSize)
而且我得到这个错误:
"Unable to create a constant value of type [...]. Only primitive types or enumeration types are supported in this context"
我敢肯定有办法做到这一点,但目前不知道如何。
答
这里是如何实现你想要的:取而代之的是
var propertyInfo = typeof(Data.Quote).GetProperty(sortName);
ParameterExpression parameter = Expression.Parameter(typeof(T), "s");
MemberExpression property = Expression.Property(parameter, propertyInfo);
LambdaExpression sort = Expression.Lambda(property, parameter);
MethodCallExpression call = Expression.Call(
typeof(Queryable),
"OrderBy",
new[] {typeof(T), property.Type},
Query.Expression,
Expression.Quote(sort));
var orderedQuery = (IOrderedQueryable<T>)Query.Provider.CreateQuery<T>(call);
PaginatedList = orderedQuery.Skip(skipValue).Take(pageSize);
答
被复制到propertyInfo
的值只是一个Object,因为这是GetProperty()
返回的类型。将鼠标悬停在var
上,您会确认。
对于对象不存在GetValue
方法,因此您需要在调用GetValue
之前将其转换为正确的类型。
答
你需要创建一个表达式来选择property.From此source:
public static class Utility
{
//makes expression for specific prop
public static Expression<Func<TSource, object>> GetExpression<TSource>(string propertyName)
{
var param = Expression.Parameter(typeof(TSource), "x");
Expression conversion = Expression.Convert(Expression.Property
(param, propertyName), typeof(object)); //important to use the Expression.Convert
return Expression.Lambda<Func<TSource, object>>(conversion, param);
}
public static IOrderedQueryable<TSource>
OrderBy<TSource>(this IQueryable<TSource> source, string propertyName)
{
return source.OrderBy(GetExpression<TSource>(propertyName));
}
}
然后你就可以订购如下所示:
var result=Query.OrderBy(sortName)...;
感谢所有的建议,我发现每个人的最佳解决方案是在答案为:http://*.com/questions/41244/dynamic-linq-orderby-on-ienumerablet – Saleh
必须把信用发现重复问题的人正是我所需要的,非常感谢! !一直在寻找这个老旧的 – Saleh