Avoid OrderBy with Include query duplication
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
### Include your code
Given entities which look like these
```C#
public class ContactFormSubmission {
[Key]
public int Id { get; set; }
public ICollection? Variables { get; set; }
}
public class ContactFormSubmissionVariable {
// Composite key
public int SubmissionId { get; set; } // ContactFormSubmission
public int VariableId { get; set; } // ContactFormVariable
[Required]
public string? Value { get; set; }
}
public class ContactFormVariable {
[Key]
public int Id { get; set; }
[Required]
public string? Name { get; set; }
}
```
If I use the following expression I get this resulting query
```C#
db.Set()
.OrderBy(s => s.Variables!.Single(v => v.VariableId == 4).Value)
.Take(3).ToList();
```
```SQL
SELECT TOP(@__p_0) [c].[Id]
FROM [ContactFormSubmissions] AS [c]
ORDER BY (
SELECT TOP(1) [c0].[Value]
FROM [ContactFormSubmissionVariable] AS [c0]
WHERE ([c].[Id] = [c0].[SubmissionId]) AND ([c0].[VariableId] = 4))
```
Which is good.
However if I use the following expression to include a collection I get another query
```C#
db.Set()
.Include(s => s.Variables)
.OrderBy(s => s.Variables!.Single(v => v.VariableId == 4).Value)
.Take(3).ToList();
```
```SQL
SELECT [t].[Id], [c1].[SubmissionId], [c1].[VariableId], [c1].[Value]
FROM (
SELECT TOP(@__p_0) [c].[Id], (
SELECT TOP(1) [c0].[Value]
FROM [ContactFormSubmissionVariable] AS [c0]
WHERE ([c].[Id] = [c0].[SubmissionId]) AND ([c0].[VariableId] = 4)) AS [c]
FROM [ContactFormSubmissions] AS [c]
ORDER BY (
SELECT TOP(1) [c0].[Value]
FROM [ContactFormSubmissionVariable] AS [c0]
WHERE ([c].[Id] = [c0].[SubmissionId]) AND ([c0].[VariableId] = 4))
) AS [t]
LEFT JOIN [ContactFormSubmissionVariable] AS [c1] ON [t].[Id] = [c1].[SubmissionId]
ORDER BY [t].[c], [t].[Id], [c1].[SubmissionId]
```
As you can see the nested SELECT and the following ORDER BY contain a duplicate expression.
The ORDER BY could use the alias created by the SELECT above it, like this:
```SQL
SELECT [t].[Id], [c1].[SubmissionId], [c1].[VariableId], [c1].[Value]
FROM (
SELECT TOP(@__p_0) [c].[Id], (
SELECT TOP(1) [c0].[Value]
FROM [ContactFormSubmissionVariable] AS [c0]
WHERE ([c].[Id] = [c0].[SubmissionId]) AND ([c0].[VariableId] = 4)) AS [c]
FROM [ContactFormSubmissions] AS [c]
ORDER BY [c]
) AS [t]
LEFT JOIN [ContactFormSubmissionVariable] AS [c1] ON [t].[Id] = [c1].[SubmissionId]
ORDER BY [t].[c], [t].[Id], [c1].[SubmissionId]
```
### Include provider and version information
EF Core version: 6.0.3
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 6.0
Contributor guide
Assessment
This issue has not been assessed yet.