EF Order by Nullable DateTime using string and nested reflection

核能气质少年 提交于 2019-12-24 08:39:27

问题


According to this question I have created my methods for ordering data sets.

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);
}

It was fine until I have tried to use it with Nullable<DateTime>, I have called Expression.Convert to box the Nullable<DateTime>, but unfortunately it throws

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.

I would like to make this more generic, but cannot came with a good idea.

I have done this, but it's dumb 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);
}

来源:https://stackoverflow.com/questions/49542031/ef-order-by-nullable-datetime-using-string-and-nested-reflection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!