Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql server does not support correlated subquery in Take(n).Tolist() #13712

Closed
damirci opened this issue Oct 22, 2018 · 3 comments · Fixed by #22897
Closed

sql server does not support correlated subquery in Take(n).Tolist() #13712

damirci opened this issue Oct 22, 2018 · 3 comments · Fixed by #22897
Assignees
Labels
area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-enhancement
Milestone

Comments

@damirci
Copy link

damirci commented Oct 22, 2018

I have a simple query with projection and correlated subquery and I have expect one query for query not N+1. I have to say that this code generates query that I expect with EF6.
and I know that query optimization added in 2.1 but I can not figure out this behavior.

Steps to reproduce

different queries are generate for each record for post.PostDisableCoins.ToList().

source.Select(post => new PostProject
            {
                
                PostDisableCoins = post.PostDisableCoins.ToList(),
                WarStartTime = post.WarStartTime,
                WarEndTime = post.WarEndTime,
                WarWinner = post.WarWinner,
                WarDeclarer = post.WarDeclarer
            });

Further technical details

EF Core version: 2.2
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system:
IDE: Visual Studio 2017 15.8.7

@ajcvickers
Copy link
Member

@damirci We have not been able to reproduce this--my test code is below. Can you post a runnable project/solution or complete code listing like mine below that reproduces the behavior you are seeing?

public class Post
{
    public int Id { get; set; }
    public ICollection<Coin> PostDisableCoins { get; set; }
    public DateTime WarStartTime { get; set; }
    public DateTime WarEndTime { get; set; }
    public string WarWinner { get; set; }
    public string WarDeclarer { get; set; }
}

public class PostProject
{
    public ICollection<Coin> PostDisableCoins { get; set; }
    public DateTime WarStartTime { get; set; }
    public DateTime WarEndTime { get; set; }
    public string WarWinner { get; set; }
    public string WarDeclarer { get; set; }
}

public class Coin
{
    public int Id { get; set; }
}

public class BloggingContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder
            .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Test;ConnectRetryCount=0");

    public DbSet<Post> Posts { get; set; }
}

public class Program
{
    public static void Main()
    {
        using (var context = new BloggingContext())
        {
            context.Database.EnsureDeleted();
            context.Database.EnsureCreated();

            context.Add(new Post { PostDisableCoins = new List<Coin> { new Coin(), new Coin()}});
            context.Add(new Post { PostDisableCoins = new List<Coin> { new Coin(), new Coin() } });
            context.SaveChanges();
        }

        using (var context = new BloggingContext())
        {
            var results = context.Set<Post>().Select(post => new PostProject
            {
                PostDisableCoins = post.PostDisableCoins.ToList(),
                WarStartTime = post.WarStartTime,
                WarEndTime = post.WarEndTime,
                WarWinner = post.WarWinner,
                WarDeclarer = post.WarDeclarer
            }).ToList();
        }
    }
}

@damirci
Copy link
Author

damirci commented Oct 23, 2018

I think I forgot Take() function, BTW here is sample code on existed data.

    class Program
    {
        static void Main(string[] args)
        {
            using (var context = new NplusOneContext())
            {
                var results = context.Set<Post>().Select(post => new PostProject
                {
                    PostDisableCoins = post.PostDisableCoins.Take(1).ToList(),
                    WarStartTime = post.WarStartTime,
                    WarEndTime = post.WarEndTime,
                    WarWinnerId = post.WarWinnerId,
                    WarDeclarerId = post.WarDeclarerId
                }).ToList();

                
            }
        }
    }

    public class NplusOneContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            => optionsBuilder
                .UseSqlServer(@"Data Source=.;Initial Catalog=Kalgram;Persist Security Info=True;User ID=kalgram;PassWord=kalgram");

        public DbSet<Post> Posts { get; set; }
        public DbSet<PostDisableCoin> PostDisableCoins { get; set; }
    }

    public class Post
    {
        [Key]
        public Guid PostId { get; set; }
        public ICollection<PostDisableCoin> PostDisableCoins { get; set; }
        public DateTime? WarStartTime { get; set; }
        public DateTime? WarEndTime { get; set; }

        public string WarDeclarerId { get; set; }

        public string WarWinnerId { get; set; }
    }

    public class PostProject
    {
        public ICollection<PostDisableCoin> PostDisableCoins { get; set; }
        public DateTime? WarStartTime { get; set; }
        public DateTime? WarEndTime { get; set; }

        public string WarDeclarerId { get; set; }

        public string WarWinnerId { get; set; }
    }

    public class PostDisableCoin
    {
        [Key]
        public int PostDisableCoinId { get; set; }
        public Guid PostId { get; set; }
        public virtual Post Post { get; set; }

        public int CoinAmount { get; set; }
    }

@damirci damirci changed the title sql server does not support correlated subquery in simple tolist() sql server does not support correlated subquery in Take(n).Tolist() Oct 23, 2018
@ajcvickers ajcvickers added this to the Backlog milestone Oct 24, 2018
@smitpatel smitpatel added the verify-fixed This issue is likely fixed in new query pipeline. label Mar 16, 2020
@bricelam bricelam modified the milestones: Backlog, MQ Sep 11, 2020
@maumar
Copy link
Contributor

maumar commented Sep 29, 2020

we use ROW_NUMBER function in 5.0 to translate this into a single query.

@maumar maumar closed this as completed Sep 29, 2020
@maumar maumar reopened this Sep 29, 2020
@maumar maumar added closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. and removed verify-fixed This issue is likely fixed in new query pipeline. labels Sep 29, 2020
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 7, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 7, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
@maumar maumar closed this as completed in 2403579 Oct 7, 2020
@ajcvickers ajcvickers modified the milestones: MQ, 6.0.0 Nov 25, 2020
@ajcvickers ajcvickers modified the milestones: 6.0.0, 6.0.0-preview1 Jan 27, 2021
@ajcvickers ajcvickers modified the milestones: 6.0.0-preview1, 6.0.0 Nov 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants