LINQ to Entities OrderBy exposure tree

I am trying to write a LINQ query for an orderBy dynamic property specified by a string value.

Here is my source code:

 Expression<Func<T, dynamic>> orderBy = i => i.GetType().GetProperty("PropertyName").GetValue(null);

When I tried to run this orderBy, I got the following exception:

LINQ to Entities does not recognize the method System.Object GetValue Method (System.Object), and this method cannot be translated into a storage expression.

I am trying to get around this by creating an expression tree that will give me the same result. The code should be able to return any type depending on the parameter, but I am having problems with the return type. If I do not convert the value, I get another error, since w Nullable DateTime cannot be converted to Object. Here is the code that I still have:

ParameterExpression pe = Expression.Parameter(typeof(T), "s");
Expression<Func<T, dynamic>> orderByExpression = Expression.Lambda<Func<T, dynamic>>(Expression.Convert(Expression.Property(pe, "PropertyName"), typeof(object)), pe);

and my new exception:

'System.Nullable`1 [[System.DateTime]]' 'System.Object. LINQ to Entities EDM- .

, ? , LINQ?

+4
1

Expression<Func<T, TT>>, , . , , .

:

IOrderedEnumerable<TEntityType> SortMeDynamically<TEntityType>(IEnumerable<TEntityType> query, string propertyname)
{
    var param = Expression.Parameter(typeof(TEntityType), "s");
    var prop = Expression.PropertyOrField(param, propertyname);
    var sortLambda = Expression.Lambda(prop, param);

    Expression<Func<IOrderedEnumerable<TEntityType>>> sortMethod = (() => query.OrderBy<TEntityType, object>(k => null));

    var methodCallExpression = (sortMethod.Body as MethodCallExpression);
    if (methodCallExpression == null)
        throw new Exception("Oops");

    var method = methodCallExpression.Method.GetGenericMethodDefinition();
    var genericSortMethod = method.MakeGenericMethod(typeof(TEntityType), prop.Type);
    var orderedQuery = (IOrderedEnumerable<TEntityType>)genericSortMethod.Invoke(query, new object[] { query, sortLambda.Compile() });

    return orderedQuery;
}

, IQueryable ( EF, )

IOrderedQueryable<TEntityType> SortMeDynamically<TEntityType>(IQueryable<TEntityType> query, string propertyname)
{
    var param = Expression.Parameter(typeof(TEntityType), "s");
    var prop = Expression.PropertyOrField(param, propertyname);
    var sortLambda = Expression.Lambda(prop, param);

    Expression<Func<IOrderedQueryable<TEntityType>>> sortMethod = (() => query.OrderBy<TEntityType, object>(k => null));

    var methodCallExpression = (sortMethod.Body as MethodCallExpression);
    if (methodCallExpression == null)
        throw new Exception("Oops");

    var method = methodCallExpression.Method.GetGenericMethodDefinition();
    var genericSortMethod = method.MakeGenericMethod(typeof(TEntityType), prop.Type);
    var orderedQuery = (IOrderedQueryable<TEntityType>)genericSortMethod.Invoke(query, new object[] { query, sortLambda });

    return orderedQuery;
}
+2

Source: https://habr.com/ru/post/1624018/


All Articles