0

I'm trying to order my IMongoqueryable collection via reflection with a property string.

Unfortunately I'm getting the message Only fields are allowed in a $sort.

private static void SetOrderBy(ref IMongoQueryable<Trade> trades, BlazorGridRequest request)
{
    var prop = typeof(Trade).GetProperty(request.OrderBy);

    if (request.OrderByDescending)
        trades = trades.OrderByDescending(t => prop.GetValue(t));
    else
        trades = trades.OrderBy(t => prop.GetValue(t));
}

Can someone help me figure out, how I can get this to work? Thanks!

Rafael Wörner
  • 299
  • 4
  • 15
  • 1
    I think what you need here is to create a custom expression and pass it into appropriate `OrderByX`: `Expression> orderExpression = (e) => e.OrderBy;` – dododo Oct 10 '21 at 19:45
  • ```Trade``` has no ```OrderBy``` Property. ```request.OrderBy``` is a string containing the name of a property of ```Trade```. so I cant use ```e.OrderBy``` in the expression... – Rafael Wörner Oct 10 '21 at 20:02
  • 1
    you can create it dynamically: https://stackoverflow.com/questions/5094489/how-do-i-dynamically-create-an-expressionfuncmyclass-bool-predicate-from-ex – dododo Oct 10 '21 at 20:13

1 Answers1

0

Thanks to dododo's comments I found the following solution:

private static void SetOrderBy(ref IMongoQueryable<Trade> trades, BlazorGridRequest request)
{
    ParameterExpression pe = Expression.Parameter(typeof(Trade), "t");
    MemberExpression me = Expression.Property(pe, request.OrderBy);
    Expression conversion = Expression.Convert(me, typeof(object));
    Expression<Func<Trade, object>> orderExpression = Expression.Lambda<Func<Trade, object>> (conversion, new[] { pe });

    if (request.OrderByDescending)
        trades = trades.OrderByDescending(orderExpression);
    else
        trades = trades.OrderBy(orderExpression);
}
Rafael Wörner
  • 299
  • 4
  • 15