@@ -13,15 +13,13 @@ public sealed class ProjectableExpressionReplacer : ExpressionVisitor
1313 {
1414 readonly IProjectionExpressionResolver _resolver ;
1515 readonly ExpressionArgumentReplacer _expressionArgumentReplacer = new ( ) ;
16- readonly QueryRootReplacer _queryRootReplacer ;
1716 readonly Dictionary < MemberInfo , LambdaExpression ? > _projectableMemberCache = new ( ) ;
18- private bool _disableRootRewrite = false ;
17+ private bool _disableRootRewrite ;
1918 private IEntityType ? _entityType ;
2019
2120 public ProjectableExpressionReplacer ( IProjectionExpressionResolver projectionExpressionResolver )
2221 {
2322 _resolver = projectionExpressionResolver ;
24- _queryRootReplacer = new ( _resolver ) ;
2523 }
2624
2725 bool TryGetReflectedExpression ( MemberInfo memberInfo , [ NotNullWhen ( true ) ] out LambdaExpression ? reflectedExpression )
@@ -41,19 +39,19 @@ bool TryGetReflectedExpression(MemberInfo memberInfo, [NotNullWhen(true)] out La
4139 }
4240
4341 [ return : NotNullIfNotNull ( nameof ( node ) ) ]
44- public override Expression ? Visit ( Expression ? node )
42+ public Expression ? Replace ( Expression ? node )
4543 {
46- var ret = base . Visit ( node ) ;
44+ var ret = Visit ( node ) ;
4745
4846 if ( _disableRootRewrite )
4947 {
5048 return ret ;
5149 }
5250
53- switch ( node )
51+ switch ( ret )
5452 {
5553 // Probably a First() or ToList()
56- case MethodCallExpression { Arguments . Count : > 0 } call when _entityType != null :
54+ case MethodCallExpression { Arguments . Count : > 0 , Object : null } call when _entityType != null :
5755 {
5856 var self = _AddProjectableSelect ( call . Arguments . First ( ) , _entityType ) ;
5957 return call . Update ( null , call . Arguments . Skip ( 1 ) . Prepend ( self ) ) ;
@@ -96,7 +94,7 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
9694 var updatedBody = _expressionArgumentReplacer . Visit ( reflectedExpression . Body ) ;
9795 _expressionArgumentReplacer . ParameterArgumentMapping . Clear ( ) ;
9896
99- return Visit (
97+ return base . Visit (
10098 updatedBody
10199 ) ;
102100 }
@@ -128,13 +126,13 @@ PropertyInfo property when nodeExpression is not null
128126 var updatedBody = _expressionArgumentReplacer . Visit ( reflectedExpression . Body ) ;
129127 _expressionArgumentReplacer . ParameterArgumentMapping . Clear ( ) ;
130128
131- return Visit (
129+ return base . Visit (
132130 updatedBody
133131 ) ;
134132 }
135133 else
136134 {
137- return Visit (
135+ return base . Visit (
138136 reflectedExpression . Body
139137 ) ;
140138 }
@@ -190,20 +188,21 @@ private Expression _AddProjectableSelect(Expression node, IEntityType entityType
190188 Expression . New ( entityType . ClrType ) ,
191189 properties . Select ( x => Expression . Bind ( x , Expression . MakeMemberAccess ( xParam , x ) ) )
192190 . Concat ( projectableProperties
193- . Select ( x => Expression . Bind ( x , _ReplaceParam ( _resolver . FindGeneratedExpression ( x ) , xParam ) ) )
191+ . Select ( x => Expression . Bind ( x , _GetAccessor ( x , xParam ) ) )
194192 )
195193 ) ,
196194 xParam
197195 )
198196 ) ;
199197 }
200198
201- private Expression _ReplaceParam ( LambdaExpression lambda , ParameterExpression para )
199+ private Expression _GetAccessor ( PropertyInfo property , ParameterExpression para )
202200 {
201+ var lambda = _resolver . FindGeneratedExpression ( property ) ;
203202 _expressionArgumentReplacer . ParameterArgumentMapping . Add ( lambda . Parameters [ 0 ] , para ) ;
204203 var updatedBody = _expressionArgumentReplacer . Visit ( lambda . Body ) ;
205204 _expressionArgumentReplacer . ParameterArgumentMapping . Clear ( ) ;
206- return updatedBody ;
205+ return base . Visit ( updatedBody ) ;
207206 }
208207 }
209208}
0 commit comments