这是我用于此的方法:
private IQueryable<T> OrderQuery<T>(IQueryable<T> query, OrderParameter orderBy)
{
string orderMethodName = orderBy.Direction == SortDirection.Ascending ? "OrderBy" : "OrderByDescending";
Type t = typeof(T);
var param = Expression.Parameter(t, "shipment");
var property = t.GetProperty(orderBy.Attribute);
/* We can't just call OrderBy[Descending] with an Expression
* parameter because the second type argument to OrderBy is not
* known at compile-time.
*/
return query.Provider.CreateQuery<T>(
Expression.Call(
typeof(Queryable),
orderMethodName,
new Type[] { t, property.PropertyType },
query.Expression,
Expression.Quote(
Expression.Lambda(
Expression.Property(param, property),
param))
));
}
OrderParameter
只是一个具有属性和方向的结构。
编辑:补充说明。
这个方法来自我的DynamicOrderList
类,它是一个OrderParameter
对象列表。如果您只需要按一个字段排序,那么您可以稍微简化一下:
private IQueryable<T> OrderByDynamic<T>(this IQueryable<T> query, string attribute, SortDirection direction)
{
try
{
string orderMethodName = direction == SortDirection.Ascending ? "OrderBy" : "OrderByDescending";
Type t = typeof(T);
var param = Expression.Parameter(t);
var property = t.GetProperty(attribute);
return query.Provider.CreateQuery<T>(
Expression.Call(
typeof(Queryable),
orderMethodName,
new Type[] { t, property.PropertyType },
query.Expression,
Expression.Quote(
Expression.Lambda(
Expression.Property(param, property),
param))
));
}
catch (Exception) // Probably invalid input, you can catch specifics if you want
{
return query; // Return unsorted query
}
}
然后像这样使用它:
myQuery = myQuery.OrderByDynamic("name", SortDirection.Ascending);
编辑2:
public IQueryable<T> OrderBy<T>(this IQueryable<T> query, string attribute, SortDirection direction)
{
return ApplyOrdering(query, attribute, direction, "OrderBy");
}
public IQueryable<T> ThenBy<T>(this IQueryable<T> query, string attribute, SortDirection direction)
{
return ApplyOrdering(query, attribute, direction, "ThenBy");
}
private IQueryable<T> ApplyOrdering<T>(IQueryable<T> query, string attribute, SortDirection direction, string orderMethodName)
{
try
{
if (direction == SortDirection.Descending) orderMethodName += "Descending";
Type t = typeof(T);
var param = Expression.Parameter(t);
var property = t.GetProperty(attribute);
return query.Provider.CreateQuery<T>(
Expression.Call(
typeof(Queryable),
orderMethodName,
new Type[] { t, property.PropertyType },
query.Expression,
Expression.Quote(
Expression.Lambda(
Expression.Property(param, property),
param))
));
}
catch (Exception) // Probably invalid input, you can catch specifics if you want
{
return query; // Return unsorted query
}
}
和:
myQuery=myQuery.OrderBy("name", SortDirection.Ascending).ThenBy("date", SortDirection.Descending);