Skip to content

Reuse complex projection in operators afterwards #7776

@msmolka

Description

@msmolka

The code generated for SQL is far from optimal comparing to EF6

Steps to reproduce

I'm getting model from database in following way:

from user in context.Users
                   let info= context.LastInfo.OrderByDescending(t => t.CreatedDate).FirstOrDefault(t => t.UserId== user.Id)
                   let extra = context.Extras.OrderByDescending(t => t.CreatedDate).FirstOrDefault(s => s.UserId == user.Id)
                   select new UserExtraInfo
                   {
                       Active = user.Active,                    
                       Id = user.Id,
                       LastInfoDate = info.CreatedDate,                    
                       LastTest1 = extra.Test1,
                       LastTest2 = extra.Test2,
                       LastTest3 = extra.Test3,                   
                       InfoTest1= info.Test1,
                       InfoTest1= info.Test2                   
                   };

The code produced by EF is

SELECT
    [user].[Active],
    [user].[Id],
(
    SELECT TOP (1)
        [t].[CreatedDate]
    FROM [Info] AS [t]
    WHERE
        [t].[UserId] = [user].[Id]
    ORDER BY
        [t].[CreatedDate] DESC
),
 
(
    SELECT TOP (1)
        [t0].[Test1]
    FROM [Extra] AS [t0]
    WHERE
        [t0].[UserId] = [user].[Id]
    ORDER BY
        [t0].[CreatedDate] DESC
),
(
    SELECT TOP (1)
        [t1].[Test2]
    FROM [Extra] AS [t1]
    WHERE
        [t1].[UserId] = [user].[Id]
    ORDER BY
        [t1].[CreatedDate] DESC
),
(
    SELECT TOP (1)
        [t2].[Test3]
    FROM [Extra] AS [t2]
    WHERE
        [t2].[UserId] = [user].[Id]
    ORDER BY
        [t2].[CreatedDate] DESC
),
(
    SELECT TOP (1)
        [t4].[Test1]
    FROM [Info] AS [t4]
    WHERE
        [t4].[UserId] = [user].[Id]
    ORDER BY
        [t4].[CreatedDate] DESC
),
(
    SELECT TOP (1)
        [t5].[Test2]
    FROM [Info] AS [t4]
    WHERE
        [t5].[UserId] = [user].[Id]
    ORDER BY
        [t5].[CreatedDate] DESC
)
FROM [User] AS [user]

As far as I remember EF6 generated following query with CROSS APPLY/OUTER APPLY which is about 10x quicker.
Instead of select multiple times from the same row projection. Select each row once using OUTER APPLY.

Further technical details

EF Core version: 1.1.0
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Window 10
IDE: Visual Studio 2015

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions