dotnet / dotnet/efcore

Stop remapping lambda bodies to deal with parameters

Open
#35,038 6 comments 1 reaction 0 assignees View on GitHub
area-query
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.