-
Type:
Task
-
Resolution: Unresolved
-
Priority:
Unknown
-
None
-
Affects Version/s: None
-
Component/s: None
-
None
Internal refactor (part of the native LINQ query provider program, epic EF-322). A code review of the native projection-pushdown work (EF-331) surfaced a set of interrelated separation-of-concerns issues where native-translation logic has accreted inside the EF Core query dispatcher and value serialization is duplicated across the two dialect renderers. Pure internal refactor — no behavior change, no public-surface break (all affected types are internal; which internal path a supported query takes is not a break per the AGENTS.md versioning rubric).
Scope (from the EF-331 review findings)
- Extract native slot/projection population out of MongoQueryableMethodTranslatingExpressionVisitor. TryPopulateNativeProjection (projection shape-walking, alias-collision detection, $project alias semantics) and the seven-arm PopulateNativeSlots (with canonical-order guards) are native-translation concerns living inline in the EF dispatcher — it is drifting toward a god-class straddling two layers. Extract a NativeSlotPopulator / NativeProjectionBinder under Query/NativeTranslation/ and have the visitor delegate.
- Hoist a shared value renderer. MongoAggregationExpressionRenderer.RenderValue/SerializeConstant re-implement MongoQueryLanguageRenderer.RenderValue/ToBsonValue; a code comment admits it must "serialize exactly as in the query renderer" — a correctness coupling enforced only by hand (and already noted as an
EF-329minor: the aggregation renderer lacks the try/catch diagnostics wrapper the query renderer has). Introduce one shared MongoValueRenderer (value-node -> BsonValue) that both dialects call. - Unify the is-native signal. Projection routing in MongoShapedQueryCompilingExpressionVisitor keys off both routing state and MongoSelectDefinition.IsNativeRepresentable, and a comment concedes the flag "does not always flip" for pushed-down projections. Two signals for one decision invite silent-wrong-result drift. Make one authoritative predicate the single source of truth and document it.
- Thread the single renderer through MongoPipelineFactory. RenderProject instantiates a fresh MongoAggregationExpressionRenderer() instead of using the threaded renderer arg (three ad-hoc instances total). Fold into the shared-renderer change.
Out of scope
- Dropping the MongoExpression : System.Linq.Expressions.Expression base (a separate judgment call — revisit only if/when a visitor-driven transform actually needs it; see later sub-projects SP4-7).
Acceptance
- No behavior change: full FunctionalTests + SpecificationTests green in Native mode on EF8/EF9/EF10; MONGODB_EF_NATIVE_ONLY=1 pass-set unchanged.
- The EF QMTEV no longer contains native-slot/projection-translation bodies (delegates to the extracted type); the two renderers share one value-rendering path; the is-native decision has a single documented predicate.