I'm trying to use an ExpressionVisitor to change a expression to be used on another underlying type.
Assume I have 2 class Foo and Bar, where Bar is a logical representation and Foo is a EF entity.
So I have a method that accepts an expression on Bar, executes a query on Foo
IEnumeable<Bar> Where(Expression<Func<Bar, bool>> barExpression){
// Do some magic
var fooExpression = (Expression<Func<Foo, bool>>) MyExpressionVisitor.Visit(barExpression);
// Execute on DbSet<Foo>
var foos = _context.Foos.Where(fooExpression);
return foos.Select(MapToBar)
}
I did find an answer that could do this: https://stackoverflow.com/a/46592531/2968001
So far so good, however, Bar does contain nested properties where Foo is Flat.
For example:
class Foo {
string MyProperty {get; set; }
}
class Bar {
Baz Baz { get; set; }
}
class Baz {
string SomeProperty {get; set; }
}
If I now do something like
.Where(bar => bar.Baz.SomeProperty.EndsWith("789");
I would like the fooExpression to be the equivalent of
foo => foo.MyProperty.EndsWith("789")
And I can not get my head around it. While I do think that at some point I got the right expression build (when the visiting node is of type Foo), It get not applied in the final Lambda
Given your
Wheremethod as follows:Then you can write an
ExpressionVisitorto replace the parameter in aFunc<Bar,bool>predicate and convert any property accessors to use the new parameter and mappedFooproperty: