Invoke MethodExpression
-
I'm struggling with a rather elaborate Expression attempt, any help will be appreciated: I have a method:
public QueryContext<T> OrderBy(Expression<Func<T, SortColumn>> orderByExpression)
that I string onto a number of methods (either the same method or some of my other methods that look similar exposed byQueryContext<T>
) in code something like this:return this.Get<DataStorageLocation>(dsl => !dsl.Deleted)
.IncludeReferencedObject(dsl => new RangedColumn<DataStorageLocation>(dsl.ChildLocations)
.Where<DataStorageLocation>(cdsl => !cdsl.Deleted)
.Where<DataStorageLocation>(cdsl => cdsl.Deleted == false)
.Where<DataStorageLocation>(cdsl => cdsl.Id > 0)
.OrderBy(cdsl => new SortColumn<DataStorageLocation>(cdsl.LocationName)))).ToList();(this is not very logical code, but gives a good debuggin example) and produces an expression something like this:
new RangedColumn`1(dsl.ChildLocations).Where(cdsl => Not(cdsl.Deleted)).Where(cdsl => (cdsl.Deleted = False)).Where(cdsl => (cdsl.Id > 0)).OrderBy(cdsl => new SortColumn`1(cdsl.LocationName))
Problem comes in when I try to invoke the OrderBy MethodExpression like this:
var args = (from a in methodCallExpression.Arguments select a as Expression).ToList();
methodCallExpression.Method.Invoke(column, args.ToArray());The Method Name that I have from
methodCallExpression.Method.Name
isOrderBy
and the arguments that I have iscdsl => new SortColumn`1(cdsl.LocationName)
which looks correct, yet I get an exception that my expression cannot be cast to 'Expression<Func<T, SortColumn>> orderByExpression
' which is my method signature so I almost understand that there is a problem, but what I don't understand is how invoking the method, with the arguments it has for itself gives an error... I've only been playing with Expressions for a (painful) couple of days, if this is a stupid question please answer it before you frag me :) PS: I've tried to write an overload method forOrderBy
that takes anExpression
object as a parameter, yet the Invoke method insists on calling the other method (which I also understand)____________________________________________________________ Be brave little warrior, be VERY brave
-
I'm struggling with a rather elaborate Expression attempt, any help will be appreciated: I have a method:
public QueryContext<T> OrderBy(Expression<Func<T, SortColumn>> orderByExpression)
that I string onto a number of methods (either the same method or some of my other methods that look similar exposed byQueryContext<T>
) in code something like this:return this.Get<DataStorageLocation>(dsl => !dsl.Deleted)
.IncludeReferencedObject(dsl => new RangedColumn<DataStorageLocation>(dsl.ChildLocations)
.Where<DataStorageLocation>(cdsl => !cdsl.Deleted)
.Where<DataStorageLocation>(cdsl => cdsl.Deleted == false)
.Where<DataStorageLocation>(cdsl => cdsl.Id > 0)
.OrderBy(cdsl => new SortColumn<DataStorageLocation>(cdsl.LocationName)))).ToList();(this is not very logical code, but gives a good debuggin example) and produces an expression something like this:
new RangedColumn`1(dsl.ChildLocations).Where(cdsl => Not(cdsl.Deleted)).Where(cdsl => (cdsl.Deleted = False)).Where(cdsl => (cdsl.Id > 0)).OrderBy(cdsl => new SortColumn`1(cdsl.LocationName))
Problem comes in when I try to invoke the OrderBy MethodExpression like this:
var args = (from a in methodCallExpression.Arguments select a as Expression).ToList();
methodCallExpression.Method.Invoke(column, args.ToArray());The Method Name that I have from
methodCallExpression.Method.Name
isOrderBy
and the arguments that I have iscdsl => new SortColumn`1(cdsl.LocationName)
which looks correct, yet I get an exception that my expression cannot be cast to 'Expression<Func<T, SortColumn>> orderByExpression
' which is my method signature so I almost understand that there is a problem, but what I don't understand is how invoking the method, with the arguments it has for itself gives an error... I've only been playing with Expressions for a (painful) couple of days, if this is a stupid question please answer it before you frag me :) PS: I've tried to write an overload method forOrderBy
that takes anExpression
object as a parameter, yet the Invoke method insists on calling the other method (which I also understand)____________________________________________________________ Be brave little warrior, be VERY brave
When your expression is '
x.Where(a => f(a))
' and the Where method takes anExpression<Func<T>>
, then the expression tree actually is:MethodCallExpression
- Object: x
- Method: Where
- Arguments:
- UnaryExpression (Type: Quote)
- LambdaExpression
- Parameter: a
- Body: f(a)
- LambdaExpression
- UnaryExpression (Type: Quote)
'Quote' is the operator that converts from a lambda to an expression tree (similar to
quote
in LISP). So you're trying to call Where with anUnaryExpression
where it expects an Expression<Func<T>>. Solution: useExpression.Lambda<TDelegate>()
to create a new typed lambda expression reusing the parameter and body from the inputLambdaExpression
. -
When your expression is '
x.Where(a => f(a))
' and the Where method takes anExpression<Func<T>>
, then the expression tree actually is:MethodCallExpression
- Object: x
- Method: Where
- Arguments:
- UnaryExpression (Type: Quote)
- LambdaExpression
- Parameter: a
- Body: f(a)
- LambdaExpression
- UnaryExpression (Type: Quote)
'Quote' is the operator that converts from a lambda to an expression tree (similar to
quote
in LISP). So you're trying to call Where with anUnaryExpression
where it expects an Expression<Func<T>>. Solution: useExpression.Lambda<TDelegate>()
to create a new typed lambda expression reusing the parameter and body from the inputLambdaExpression
.Hi Daniel, Thanks, will give this a try
____________________________________________________________ Be brave little warrior, be VERY brave