Query: further improve translation of queries with Distinct or Groupby in correlated subquery, when entity identifiers are not easy to obtain

Open
#26,077 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Stale
Tech stack
csharp
Domain
databases

Research direction

Start with the correlated query example named Correlated_collection_with_distinct_not_projecting_identifier_column_also_projecting_complex_expressions and compare it with the current handling of Distinct and GroupBy projections. The change is complete when complex projections such as g.OwnerFullName.Length can be used to preserve row uniqueness in the correlated subquery without requiring entity identifiers.

Written by the indexing model from the issue text.

Description

area-groupby area-query

Improvement on https://github.com/dotnet/efcore/issues/22049. Currently, when we don't have access to "natural" identifiers, (so we can't inject orderby to properly bucket the results in case of correlated subquery - this can happen for GroupBy and Distinct) we try to use what we have - entire projection in case of distinct and grouping key in case of GroupBy. Those still guarantee the uniqueness of the row, so it's ok to use them. However, current limitation is that we only do this if the entire projection is made of columns - we don't do it for anything more complex, say x.Name.Length. It should be perfectly fine to use more complex projection as it still guarantees the uniqueness of the row. The reason why we have the limitation is that we didn't have an easy way to get the proper comparer for this complex expression (in case of columns we use the comparer from type mapping).

Example of the query that could work: Correlated_collection_with_distinct_not_projecting_identifier_column_also_projecting_complex_expressions

ss.Set<Gear>()
                    .Select(
                        g => new
                        {
                            Key = g.Nickname,
                            Subquery = g.Weapons
                                .Select(w => new { w.Name, w.IsAutomatic, w.OwnerFullName.Length })
                                .Distinct().ToList()
                        }
Dominant language
C#
Stars
14.8k
Forks
3.4k
Avg merge
2d 5h
Merged PRs (30d)
134

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from dotnet/efcore

All issues in dotnet/efcore

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.