dotnet / dotnet/efcore

Scalar collections: stop expanding bare arrays to a subquery when ToList() is composed on top

Open
#34,081 0 comments 0 reactions 0 assignees View on GitHub
area-primitive-collections area-query
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

See PrimitiveCollectionsQueryTestBase.Project_collection_of_ints_with_ToList_and_FirstOrDefault:

```c#
public virtual Task Project_collection_of_ints_with_ToList_and_FirstOrDefault(bool async)
=> AssertFirstOrDefault(
async,
ss => ss.Set().OrderBy(x => x.Id).Select(x => x.Ints.ToList()),
asserter: (e, a) => AssertCollection(e, a, elementSorter: ee => ee));
```

SQL Server SQL:

```sql
SELECT [p0].[Id], CAST([i].[value] AS int) AS [value], [i].[key]
FROM (
SELECT TOP(1) [p].[Id], [p].[Ints]
FROM [PrimitiveCollectionsEntity] AS [p]
ORDER BY [p].[Id]
) AS [p0]
OUTER APPLY OPENJSON([p0].[Ints]) AS [i] -- We should just be projecting `[p0].[Ints]` out directly, no need for OPENJSON
ORDER BY [p0].[Id], CAST([i].[key] AS int)
```

Cosmos SQL:

```sql
SELECT ARRAY( -- same thing, no need for an ARRAY() subquery
SELECT VALUE i
FROM i IN c["Ints"]) AS c
FROM root c
WHERE (c["Discriminator"] = "PrimitiveCollectionsEntity")
ORDER BY c["Id"]
OFFSET 0 LIMIT 1
```

This is the result of composing ToList() on top of a bare array (ToList() is one of the major things enabled by this PR)... This is actually quite complicated, since the CLR type of the array (`int[]`) can't just be cast (in the shaper) to a `List`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.