Skip to content

Fix GroupBy.Select EmptyProjectionMember#38140

Open
henriquewr wants to merge 1 commit intodotnet:mainfrom
henriquewr:emptyProjectionMember
Open

Fix GroupBy.Select EmptyProjectionMember#38140
henriquewr wants to merge 1 commit intodotnet:mainfrom
henriquewr:emptyProjectionMember

Conversation

@henriquewr
Copy link
Copy Markdown
Contributor

@henriquewr henriquewr commented Apr 19, 2026

"partially" fixes #30052, #31209 and probably others

The issue was that the QueryExpression instance is the same reference as the external instance
So the inner projection was wrongly applied to the external too

This fixes the original EmptyProjectionMember error, now GroupBy(...).Select(...).Where(...) (or any method that follows the Select call, as long as it is not other Select call) works, but isn't the entire thing

If the Select call following a GroupBy falls back to _indexBasedBinding (RelationalProjectionBindingExpressionVisitor or InMemory) GroupBy(...).Select(SomethingThatFallsbackToIndexBasing)
it is no longer possible to apply any projection that doesn't also falls back to _indexBasedBinding
This occurs because the second projection cannot override the previous one (_clientProjection has a projection and _projectionMapping has other projection)

It seems that this entire thing is caused because the GroupBy version of NavigationExpandingExpressionVisitor.ProcessSelect which does not return a pending selector. Instead, it returns a direct Select call that is not extensible

I tested the approach returning a pending selector, which resolved the issue (allowing GroupBy(...).Select(SomethingThatFallsbackToIndexBasing).Select(...) to work)
However doing it generates lots of other problems, it would need a different approach to how pending selectors are handled

Certain methods would need to resolve the pending selector before the call
GroupBy().Select().Join(), Join would need to resolve the pending selector before the call

At least a workaround exists:

Instead of chaining Select calls:

GroupBy()
.Select()
.Select()

You can nest Select calls:

GroupBy()
.Select(x => x.Select(...))

About the skipped InMemory test:

It seems to be caused by the same issue

GroupBy()
.Select(SelectorFunc)
.Where(valueOfTheSelectCall => valueOfTheSelectCall == something)

Is supposed to be transformed into

GroupBy
.Where(SelectorFunc == something)
.Select(SelectorFunc)

And since GroupBy.Select does not return a pending selector, the Where call fails to retrieve the value

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Combination of GroupBy, FirstOrDefault and Select throws a KeyNotFoundException

2 participants