0

I have two expressions, of the same type:

Expression<Func<IQueryable<T>, IQueryable<T>>> exprA, exprB;

I would like to combine these two expressions, so that semantically it comes out as

a(b(T))

But I can't find the right syntax, even with LinqKit.

var exprC = exprA.Invoke(exprB); // doesn't work

How do you do this?

Shaul Behr
  • 36,951
  • 69
  • 249
  • 387

2 Answers2

1

If your types are truly Expressions, you want this:

var c = x => a.Compile()(b.Compile()(x));

Otherwise if they are Functions:

var c = x => a(b(x));

is enough.

ThreeFx
  • 7,250
  • 1
  • 27
  • 51
1

I think I understand what you're trying to do, the order of this might be wrong (if so just switch the position of f1 and f2 on the 4th line).

Expression<Func<string, string>> f1 = (s) => "hello" + s;
Expression<Func<string, string>> f2 = (s) => s + s;
var parameter = Expression.Parameter(typeof(string), "p1");
Expression<Func<string, string>> ffinal = Expression.Lambda<Func<string, string>>(Expression.Invoke(f1, Expression.Invoke(f2, parameter)), parameter);
Console.WriteLine(ffinal.ToString());
Console.WriteLine(ffinal.Compile()("123"));

when calling ffinal it takes to string passed in, calls f2 and the result of that gets passed into f1, so the printed string is hello123123

also of interest logging the expression to string gives you this

p1 => Invoke(s => ("hello" + s), Invoke(s => (s + s), p1))
Eluvatar
  • 2,265
  • 19
  • 24
  • it's worth noting that this is basically making this: `(p1) => f1(f2(p1))`, if you are worried about efficiency, you could get the body of each lambda function replace the parameters and compile it into this: `(p1) => "hello" + (p1 + p1)"` that could be more efficient but a bit more complicated than my one liner. – Eluvatar Sep 18 '16 at 09:16