-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Minor - P4
-
Affects Version/s: None
-
Component/s: None
-
None
-
Dotnet Drivers
-
Not Needed
-
None
-
None
-
None
-
None
-
None
-
None
Summary
A projection that mixes a whole entity reference with a computed-arithmetic leaf, e.g.:
db.Customers.Select(c => new { c, Total = c.Age * c.Score })
returns silently wrong values under the default Native query mode: the whole-entity fields materialize correctly, but the computed Total comes out as Score * Score (the second operand squared) instead of Age * Score. No exception is thrown.
Root cause
This shape falls back to the mixed projection shaper (MongoMixedProjectionBindingRemovingExpressionVisitor, engaged because the projection contains an entity reference). That visitor's TryResolveFieldAccess only understands MemberExpression / MethodCallExpression leaves; it has no handling for a BinaryExpression-mapped (arithmetic) leaf. The projection-binding visitor's default walk decomposes c.Age * c.Score into two separate MemberExpression visits that write the same ProjectionMember dictionary slot, so the second operand overwrites the first, yielding Score * Score.
Pre-existing — NOT introduced by the native-arithmetic-computed-projection slice
This bug pre-dates the "native arithmetic computed projections" work (commit ad72ae2 on the NativeQueryOngoing line). That slice made pure-scalar arithmetic projections native, and its MongoProjectionBindingExpressionVisitor arithmetic case is deliberately gated on Route == NativeRoute.Projection, so a mixed projection (which is Route == Fallback) never reaches it — the slice neither fixes nor worsens this shape.
Repro / documenting test
NativeComputedProjectionTests.Mixed_whole_entity_and_computed_leaf_is_a_known_preexisting_limitation pins the current wrong behavior (asserts Total == Score*Score, with an XML-doc comment marking it a known pre-existing limitation).
Suggested fix
Teach the mixed projection shaper (MongoMixedProjectionBindingRemovingExpressionVisitor / the shared TryResolveFieldAccess path) to handle a computed BinaryExpression-mapped projection leaf — i.e. evaluate the arithmetic client-side over the materialized document rather than reading a non-existent field / clobbering a single slot. Update the documenting test to assert the correct value once fixed.