Given a lambda that takes an Identification object, and returns a property:
Expression<Func<Identification, object>> fx = _ => _.Id;
And a conversion lambda that converts an object into an Identification instance:
ParameterExpression p = Expression.Parameter(typeof(object), "o");
Expression @new = Expression.Lambda(Expression.Convert(p, typeof(Identification)), p);
How do I build a new lambda that executes @new (getting out the Identification Instance) and passes the result into fx. I need @new's result to bind to the first parameter of fx somehow, and I cannot find an example.
I need the result to be an Expression, it should be of type Expression<Func<object, object>> and it should convert the inbound parameter to an Identification and then get the Id property.
Firstly, note that this is easier if you type @new appropriately, i.e.:
LambdaExpression @new = ...
since that provides easy access to @new.Body and @new.Parameters; that done,
Expression.Invoke can be useful here:
var combinedParam = Expression.Parameter(typeof(object), "o");
var combined = Expression.Lambda<Func<object, object>>(
    Expression.Invoke(fx,
        Expression.Invoke(@new, combinedParam)), combinedParam);
although for a cleaner expression, you can also use ExpressionVisitor to completely replace the inner expressions:
var injected = new SwapVisitor(fx.Parameters[0], @new.Body).Visit(fx.Body);
var combined = Expression.Lambda<Func<object, object>>(injected,@new.Parameters);
with:
class SwapVisitor : ExpressionVisitor {
    private readonly Expression from, to;
    public SwapVisitor(Expression from, Expression to) {
        this.from = from;
        this.to = to;
    }
    public override Expression Visit(Expression node) {
        return node == from ? to : base.Visit(node);
    }
}
what this does is:
fx.Body tree, replacing all instances of _ (the parameter) with the @new.Body (note that this will contain references to the o parameter (aka p)@new, which ensures that the values we injected will be bound correctlyUsing the code from Marc Gravell's answer, you can simplify this really nicely with a helper function:
public static class ExpressionHelper {
    public static Expression<Func<TFrom, TTo>> Chain<TFrom, TMiddle, TTo>(
        this Expression<Func<TFrom, TMiddle>> first,
        Expression<Func<TMiddle, TTo>> second
    ) {
        return Expression.Lambda<Func<TFrom, TTo>>(
           new SwapVisitor(second.Parameters[0], first.Body).Visit(second.Body),
           first.Parameters
        );
    }
    private class SwapVisitor : ExpressionVisitor {
        private readonly Expression _from;
        private readonly Expression _to;
        public SwapVisitor(Expression from, Expression to) {
            _from = from;
            _to = to;
        }
        public override Expression Visit(Expression node) {
            return node == _from ? _to : base.Visit(node);
        }
    }
}
Now look how clean that is!
var valueSelector = new Expression<Func<MyTable, int>>(o => o.Value);
var intSelector = new Expression<Func<int, bool>>(x => x > 5);
var selector = valueSelector.Chain<MyTable, int, bool>(intSelector);
And it works with Entity Framework and other things that need a clean Expression that doesn't try to invoke a Func within it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With