根据这个question,我创建了我的数据集排序方法。
public static IOrderedQueryable<T> Order<T>(this IQueryable<T> source, string propertyName,
ListSortDirection direction = ListSortDirection.Ascending)
{
return ListSortDirection.Ascending == direction
? source.OrderBy(ToLambda<T>(propertyName))
: source.OrderByDescending(ToLambda<T>(propertyName));
}
private static Expression<Func<T, object>> ToLambda<T>(string propertyName)
{
var propertyNames = propertyName.Split('.');
var parameter = Expression.Parameter(typeof(T));
var body = propertyNames.Aggregate<string, Expression>(parameter, Expression.Property);
return Expression.Lambda<Func<T, object>>(Expression.Convert(body, typeof(object)), parameter);
// return Expression.Lambda<Func<T, object>>(body, parameter);
}
在我尝试将其与Nullable<DateTime>
一起使用之前一切正常,我已调用Expression.Convert
来封装Nullable<DateTime>
,但遗憾的是它会抛出
Unable to cast the type 'System.Nullable`1[[System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types.
我想让这更通用,但不能带来好主意。
我已经这样做了,但它的哑巴AF:D
public static IOrderedQueryable<T> Order<T>(this IQueryable<T> source, string propertyName,
ListSortDirection direction = ListSortDirection.Ascending)
{
if (propertyName.Contains("date", StringComparison.CurrentCultureIgnoreCase))
{
return ListSortDirection.Ascending == direction
? source.OrderBy(ToLambda<T, DateTime?>(propertyName))
: source.OrderByDescending(ToLambda<T, DateTime?>(propertyName));
}
return ListSortDirection.Ascending == direction
? source.OrderBy(ToLambda<T, object>(propertyName))
: source.OrderByDescending(ToLambda<T, object>(propertyName));
}
private static Expression<Func<T, A>> ToLambda<T, A>(string propertyName)
{
var propertyNames = propertyName.Split('.');
var parameter = Expression.Parameter(typeof(T));
var body = propertyNames.Aggregate<string, Expression>(parameter, Expression.Property);
return Expression.Lambda<Func<T, A>>(Expression.Convert(body, typeof(A)), parameter);
// return Expression.Lambda<Func<T, object>>(body, parameter);
}