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

Global query filter trigger each other causing stack overflow in EF Core 3.1 #19211

Closed
Andrioden opened this issue Dec 6, 2019 · 6 comments
Closed

Comments

@Andrioden
Copy link

When upgrading from EF Core 2.2.2 to 3.1.0 query filteres changed behavior to causing a stack overflow for my project. After carefully testing this with incremental code changes I am fairly certain that this is because of two different global queries trigger eachother in a loop.

Considering it, I do not find it an unreasonable behavior, but I would expect the behavior to be that global query filters dont trigger other global filters. But if this is expected behavior I respect that and will have to reconsider how to solve this for my situation, which do not have an obvious solution to me.

Steps to reproduce

Here is a stripped version of the relevant code, the actual code is more complex, but should get the point accross.

Model classes

[Table(nameof(Order))]
public class Order
{
    public int Id { get; set; }
}

[Table(nameof(OrderLine))]
public class OrderLine
{
    public int Id { get; set; }

    [Required]
    public int OrderId { get; set; }
    public Order Order { get; set; }
}

DBContext

public class DBContext : IdentityDbContext<User>
{
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Order>().HasQueryFilter(o =>
            o.UserId == _userService.GetUserId() ||
            // NOTE 1 - The following line loops to NOTE 2
            o.Lines.All(/* Custom domain authorization */)
        );
        modelBuilder.Entity<OrderLine>().HasQueryFilter(l =>
            // NOTE 2 - The following line loops to NOTE 2
            l.Order.UserId == _userService.GetUserId() ||
        );

    }
}

Gives Stack overflow. in the Visual Studio 2019 "ASP.NET Core Web Server" output window.

return await _context.Orders
    .Where(o =>
        o.UserId == userId
    )
    .OrderByDescending(o => o.Id)
    .Select(o => o.Id)
    .FirstOrDefaultAsync();

Works fine

return await _context.Orders
    .IgnoreQueryFilters()
    .Where(o =>
        o.UserId == userId
    )
    .OrderByDescending(o => o.Id)
    .Select(o => o.Id)
    .FirstOrDefaultAsync();

Further technical details

EF Core version: 3.1.0 (I assume it is derived from runtime framework which 3.1.0)
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL
Target framework: netcoreapp3.1
Operating system: Windows 10 Pro
IDE: Microsoft Visual Studio Community 2019, Version 16.4.0

@smitpatel
Copy link
Contributor

Global query filters expanding other filers is expected behavior. The best we could do here is throw better exception message then stackoverflow.

@Andrioden
Copy link
Author

@smitpatel I understand. You can also consider adding it to the breaking api changes of the migration guide, if not to small of a detail.

@smitpatel
Copy link
Contributor

ref: #13361

@Andrioden - Thanks. We will add it there too.

@ajcvickers ajcvickers added this to the Backlog milestone Dec 9, 2019
@ajcvickers
Copy link
Contributor

Triage: backlog for better exception message here.

@smitpatel
Copy link
Contributor

Duplicate of #17042

@smitpatel smitpatel marked this as a duplicate of #17042 Dec 10, 2019
@roji roji changed the title Global query filter trigger eachother causing stack overflow in EF Core 3.1 Global query filter trigger each other causing stack overflow in EF Core 3.1 May 10, 2020
@ajcvickers ajcvickers modified the milestones: Backlog, 6.0.0 Nov 5, 2020
@smitpatel smitpatel removed this from the 6.0.0 milestone Aug 16, 2021
@molopony
Copy link

Global query filters expanding other filers is expected behavior. The best we could do here is throw better exception message then stackoverflow.

I don't understand why this is expected behaviour? Why would EF assume a QueryFilter (carefully designed by me) on an entityType needs additional (recursive) Queryfilters to be applied?

Suppose I don't want to recursively apply QueryFilters to QueryFilters, what is the easiest way to accomplish this?

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants