在 linq 查询中设置动态排序名称字段

Sal*_*leh 2 .net c# linq entity-framework linq-to-sql

我希望能够OrderBy使用 lambda 表达式进行查询,以便获得带有 TOP(n) 关键字的 SQL 查询(性能大幅提升)。

如果我指定的话我就能做到这一点...

PaginatedList = query.OrderBy(x => x.QuoteID).Skip(() => skipValue).Take(() => pageSize)
Run Code Online (Sandbox Code Playgroud)

但因为我希望 orderBy 字段通过 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)
Run Code Online (Sandbox Code Playgroud)

这给了我错误:

“LINQ to Entities 无法识别‘System.Object GetValue(System.Object)’方法,并且该方法无法转换为存储表达式。”

我试过这不是类型Expression<Func<T, object>>

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)
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

“无法创建 [...] 类型的常量值。在此上下文中仅支持原始类型或枚举类型”

我确信有一种方法可以实现这一目标,但目前不确定如何实现。

wdo*_*jos 5

以下是如何实现您想要的:

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);
Run Code Online (Sandbox Code Playgroud)