Stop remapping lambda bodies to deal with parameters
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
When EF translates a lambda (e.g. `Where(b => b.Name == foo)`, before actually translating the lambda body, we currently run "RemapLambdaBody"; this does a recursive search-and-replace pass, replacing instances of the ParameterExpression (`b`) with e.g. StructuralTypeShaperExpression. This way, when RelationalSqlTranslatingExpressionVisitor runs, it encounters the shaper rather than the ParameterExpression.
This extra path is bad for performance: the tree is almost always rewritten (it's not just a read-only pass), and multiple lambdas can be nested, leading to the same fragment being rewritten again and again (e.g. `blogs.Where(b => b.Posts.Where(p => p.Comments.Where(c => ...)))`).
In addition, this means that RelationalSqlTranslatingExpressionVisitor lacks context during visitation, and cannot know that it's visiting what used to be a lambda parameter. This is blocking work on #32980.
Note the similarity with #31309, which tracks removing another pre-visitation pass for handling owned navigations inside the lambda body.
Contributor guide
Assessment
This issue has not been assessed yet.