先代码,后解释。
IQueryable<T> data = this.Database.ObjectsOfType<T>();
var eachItem = Expression.Parameter(typeof(T), "item");
var propertyToOrderByExpression = Expression.Property(eachItem, propertyName);
var runMe = Expression.Call(
typeof(Queryable),
"OrderBy",
new Type[] { data.ElementType, typeof(IComparable) },
data.Expression,
Expression.Lambda<Func<T,IComparable>>(propertyToOrderByExpression, new ParameterExpression[] { eachItem }));
因此,首先我们将数据作为可查询对象来获取。它有一种“根”表达式属性,我们需要它。
eachItem 是一个表达式,表示 Lambda 中的参数占位符,如果您愿意的话,可以使用 goto 中的符号。
然后我们创建一个表达式,对用户在 propertyName 中指定的属性名称执行读取操作。
我们最终构建一个表达式,它对可查询数据调用 OrderBy 方法。我们说(按论证顺序):
Expression.Call(
[what's the type on which we want to call a method?],
[what's the name of the method we're calling?],
[if this method is generic, what are the types it deals with?],
{
[expression representing the data],
[expression for the lambda using the reader exp + each item exp]
})
最后两个位于 { } 中,因为它实际上是一个参数数组。我使用了 IComparable,因为该属性可以是任何类型,但显然需要进行比较才能订购。
Luke