dotnet / dotnet/efcore

AsSplitQuery generates incorrect sql if Convert(date, ...) is used

Open
#32,958 5 comments 1 reaction 0 assignees View on GitHub
area-query customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

Hello,

after migration from Ef6 to EfCore we found one issue. Unfortunately I can't provide the source code, but can explain the issue and show examples in the generated sql.
The issue appear if we use the `.Date` property from the `DateTime` object to truncate the time from the database column. We also have some dynamically build groupings and many includes. Therefore wanted to use `AsSplitQuery()` to reduce count of returned columns. But the generated sql is invalid:

the first query:
```sql
SELECT [t].[P0], COUNT(*)
FROM (
SELECT CONVERT(date, [l].[ValueDate]) AS [P0]
FROM [] AS [l]
WHERE EXISTS (
SELECT 1
FROM [] AS [a]
WHERE (CASE
WHEN [a].[X] = 25 THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END & CASE
WHEN [a].[ClientID] = [l].[ClientId] THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END) = CAST(1 AS bit))
) AS [t]
GROUP BY [t].[P0]
ORDER BY [t].[P0]
OFFSET 0 ROWS FETCH NEXT 300 ROWS ONLY
```

notice the `CONVERT(date, [l].[ValueDate]) AS [P0]` ?

then the second query:
```sql
SELECT [t1].[Currency], [t1].[c], [t0].[P0]
FROM (
SELECT [t].[P0], date AS [c] <--- Here date again
FROM (
SELECT CONVERT(date, [l].[ValueDate]) AS [P0]
FROM [] AS [l]
WHERE EXISTS (
SELECT 1
FROM [] AS [a]
WHERE (CASE
WHEN [a].[CGID] = 25 THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END & CASE
WHEN [a].[ClientID] = [l].[ClientId] THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END) = CAST(1 AS bit))
) AS [t]
GROUP BY [t].[P0]
ORDER BY [t].[P0]
OFFSET 0 ROWS FETCH NEXT 300 ROWS ONLY
) AS [t0]
CROSS APPLY (
...
)
```

And we get an sql server error, that column `date` doesn't exists. Which is true.
The query without splitting looks like:
```sql
SELECT [t0].[P0], [t1].[Currency], [t1].[c], [t0].[c]
FROM (
SELECT [t].[P0], COUNT(*) AS [c]
FROM (
SELECT CONVERT(date, [l].[ValueDate]) AS [P0]
FROM [Tabke] AS [l]
WHERE EXISTS (
SELECT 1
FROM [Another Table] AS [a]
WHERE (CASE
WHEN [a].[CGID] = 25 THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END & CASE
WHEN [a].[ClientID] = [l].[ClientId] THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END) = CAST(1 AS bit))
) AS [t]
GROUP BY [t].[P0]
ORDER BY [t].[P0]
OFFSET 0 ROWS FETCH NEXT 300 ROWS ONLY
) AS [t0]
OUTER APPLY (
...
)
```

it looks like the `[P0]` column additionally gets `date` in the name between queries.

### Include provider and version information

EF Core version: 7.0.15
Database provider:Microsoft.EntityFrameworkCore.SqlServer
Target framework: NET 6.0
Operating system: Windows 10
IDE: rider 2023

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.