0

Say I have two classes like the following:

public class A
{
  public B B { get; set; }
}
public class B
{
  public string SomeValue { get; set; } 
}

And the following expressions:

using System.Linq.Expressions;
// Actual expression much more complicated
Expression<Func<B, string>> mainExpression = b => b.SomeValue; 
Expression<Func<A, B>> aToB = a => a.B;

How would I combine them? Obviously I could write

Expression<Func<A, string>> newExpression = a => a.B.SomeValue;

But the real "mainExpression" is much more complicated and I'd like to avoid code duplication.

I'm using EntityFramework, these are classes representing database tables, which is why I need a System.Linq.Expressions.Expression object.

Adam
  • 817
  • 8
  • 16

1 Answers1

0

You can replace parameter of mainExpression with a body of aToB (for example using ReplacingExpressionVisitor available since EF Core 3.0 or write your own one if you are using earlier version) and build a new expression tree:

Expression<Func<B, string>> mainExpression = b => b.SomeValue; 
Expression<Func<A, B>> aToB = a => a.B;
var visit = new ReplacingExpressionVisitor(new[] {mainExpression.Parameters[0]}, new[] {aToB.Body})
    .Visit(mainExpression.Body);
var result = Expression.Lambda<Func<A, string>>(visit, aToB.Parameters);
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • Does this work with EF still do you know? – Adam Jul 21 '21 at 21:33
  • @Adam yes, it should (depends on actual expressions though). Have you tried it? – Guru Stron Jul 21 '21 at 21:34
  • I'll have to write my own I think. I'm using EF6 but this definitely helps. – Adam Jul 21 '21 at 21:43
  • @GuruStron: Can I ask how you'd use this class to replace a parameter with a newly defined `ParameterExpression`? I was using a custom `ExpressionVisitor` class. But I'm not sure what the arguments should be to the `ReplacingExpressionVisitor` constructor. – Jonathan Wood Aug 03 '21 at 23:42
  • @GuruStron: Thanks, the first argument is the one giving me trouble. Looks like in your case it's just the first parameter to your expression. Unfortunately, I have my code working with a plain `Expression`, which has no `Parameters` property. And I'm having trouble working through the errors when I change the expression to a lambda. – Jonathan Wood Aug 04 '21 at 01:05
  • @JonathanWood can you please show the code? – Guru Stron Aug 04 '21 at 01:45
  • @GuruStron: I would appreciate it. I've created a new question [here](https://stackoverflow.com/questions/68644895/replace-custom-expressionvisitor-with-replacingexpressionvisitor). – Jonathan Wood Aug 04 '21 at 03:08