Can't build lambda Expression with unknown type of a property

c# entity-framework expression-trees linq

Question

I am building a helper method that returns an expression based on a property that could be used in an orderby or where, etc. in a linq to entities operation.

I won't know the type of the property upfront, so I have declared it as object and dynamic and have also tried to use Expression.Convert but it will not work for non string typed properties.

The current property type that is not a string that I'm working with is int? and the error I get is

Expression of type 'System.Nullable`1[System.Int32]' cannot be used for return type 'System.Object';

Code:

var param = Expression.Parameter(typeof(Employee), "x");
MemberExpression propExp = Expression.Property(param, "somePropertyName");
Expression.Lambda<Func<Employee, object>>(propExpression, param);

AS I said, I've used object and dynamic in line above with same results. I've also tried to convert it to the right type but that doesn't work:

Expression conversion = Expression.Convert(propExp, ((PropertyInfo)propExp.Member).PropertyType)

While I'm in debug mode and I try this, Expression.Lambda(conversiona, param), it seems to work

{x => Convert(x.EmployeeNo)}
Body: {Convert(x.EmployeeNo)}
CanReduce: false
DebugView: ".Lambda #Lambda1<System.Func`2[xx.DomainModel.Entities.Employee,System.Nullable`1[System.Int32]]>(xx.DomainModel.Entities.Employee $x)\r\n{\r\n    (System.Nullable`1[System.Int32])$x.EmployeeNo\r\n}"
Name: null
NodeType: Lambda
Parameters: Count = 1
ReturnType: {Name = "Nullable`1" FullName = "System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}
TailCall: false
Type: {Name = "Func`2" FullName = "System.Func`2[[xx.DomainModel.Entities.Employee, Fng.Facts.DomainModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}

...but when I use it in an orderby I get

error CS1503: Argument 2: cannot convert from 'System.Linq.Expressions.LambdaExpression' to 'string'

I thought that maybe I needed to dynamically build the Expression.Lambda using the correct type as I inspect it but haven't tried that yet

Thanks for any help

1
1
11/13/2016 10:34:28 AM

Popular Answer

Convert it to object by

Expression conversion = Expression.Convert(propExp, typeof(object))

That should be ok to be returned, but then you will have to deal with these converts on the other side, where you do the Orderby.

    private IQueryable<T> AddOrderBy<T>(IQueryable<T> query, Expression<Func<T, object>> orderByProperty, bool isAscending, bool isFirst)
{
    Expression<Func<IOrderedQueryable<int>, IQueryable<int>>> methodDef = isAscending 
        ? (isFirst ? (Expression<Func<IOrderedQueryable<int>, IQueryable<int>>>)(q => q.OrderBy(x => x)) : (Expression<Func<IOrderedQueryable<int>, IQueryable<int>>>)(q => q.ThenBy(x => x)))
        : (isFirst ? (Expression<Func<IOrderedQueryable<int>, IQueryable<int>>>)(q => q.OrderByDescending(x => x)) : (Expression<Func<IOrderedQueryable<int>, IQueryable<int>>>)(q => q.ThenByDescending(x => x)));

    // get the property type
    var propExpression = orderByProperty.Body.NodeType == ExpressionType.Convert && orderByProperty.Body.Type == typeof(object)
        ? (LambdaExpression)Expression.Lambda(((UnaryExpression)orderByProperty.Body).Operand, orderByProperty.Parameters)
        : orderByProperty;

    var methodInfo = ((MethodCallExpression)methodDef.Body).Method.GetGenericMethodDefinition().MakeGenericMethod(typeof(T), propExpression.Body.Type);
    return (IQueryable<T>)methodInfo.Invoke(null, new object[]{query, propExpression});
}
1
11/13/2016 9:19:44 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow