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

Query exception after upgrading from 6.0.1 to 6.0.2 #27600

Closed
MariovanZeist opened this issue Mar 9, 2022 · 4 comments
Closed

Query exception after upgrading from 6.0.1 to 6.0.2 #27600

MariovanZeist opened this issue Mar 9, 2022 · 4 comments
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 regression Servicing-approved type-bug
Milestone

Comments

@MariovanZeist
Copy link

MariovanZeist commented Mar 9, 2022

After upgrading all packages to 6.03 I have a query that fails.
(Problem also occurs when upgrading from 6.0.1 to 6.0.2)

I have the following query (The DbContext is the default IdentityDbContext)
(The query gets the user roles from the user)

var roles = await ctx.Users.Where(u => u.Id == userId).Select(u => u.Roles.Select(r => r.Name)).FirstOrDefaultAsync();

in 6.0.1 it returns an IEnumerable<string> containing the roles
in 6.0.3 (and 6.0.2) it generates an exception:

Expression of type 'System.Threading.Tasks.Task`1[System.Collections.Generic.List`1[System.String]]' cannot be used for return type 'System.Threading.Tasks.Task`1[System.Collections.Generic.IEnumerable`1[System.String]]'"}

with the following stacktrace:

   at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expression& body, ReadOnlyCollection`1 parameters, String paramName)
   at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String name, Boolean tailCall, IEnumerable`1 parameters)
   at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Boolean tailCall, IEnumerable`1 parameters)
   at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, ParameterExpression[] parameters)
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, Expression expression, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.FirstOrDefaultAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)

To reproduce:
https://github.com/MariovanZeist/EFCoreTest

and follow the readme

I am (trying) to use EF Core 6.03
Database provider: (e.g. Microsoft.EntityFrameworkCore.SqlServer)
Target framework: (e.g. .NET 6.0)
Operating system: Windows VS 2022 (17.1)

@MariovanZeist MariovanZeist changed the title Exceptions after upgrading from 6.0.1 to 6.0.3 Exceptions after upgrading from 6.0.1 to 6.0.3/6.0.2 Mar 9, 2022
@maumar
Copy link
Contributor

maumar commented Mar 9, 2022

@MariovanZeist In order to fix the problem add ToList to the collection inside the projection:

var roles = await ctx.Users.Where(u => u.Id == Guid.NewGuid()).Select(u => u.Roles.Select(r => r.Name).ToList()).FirstOrDefaultAsync();

@MariovanZeist
Copy link
Author

Thanks @maumar
I ended up using

  var roles = await ctx.Users.Where(u => u.Id == userId).SelectMany(u => u.Roles.Select(r => r.Name)).ToListAsync();

But I have several more queries that fail after the upgrade so I was forced to revert back to 6.0.1.

@MariovanZeist
Copy link
Author

I can circumvent the problem by adding

  AppContext.SetSwitch("Microsoft.EntityFrameworkCore.Issue27105", true);

To my startup code

I believe the problem has been introduced here: #27134

So I will test to see if this alleviates my problems, so I can upgrade to 6.0.3.

smitpatel added a commit that referenced this issue Mar 17, 2022
This improves the fix made in #27134

In earlier PR we converted `IQueryable<T>` to `IEnumerable<T>` becaused we converted enumerable to queryable during preprocessing phase and types aligned in later phase since we create a list (which does implement `IEnumerable<T>`). Though this implementing behavior doesn't work when returning a single result of enumerable during async which wraps collection type inside Task.
The better fix is to assign `List<T>` as type since we are eventually creating a list.
In case of single result, the single result operator has generic type which will introduce convert node into it automatically which will match types for async tasks.

Resolves #27600
smitpatel added a commit that referenced this issue Mar 17, 2022
This improves the fix made in #27134

In earlier PR we converted `IQueryable<T>` to `IEnumerable<T>` becaused we converted enumerable to queryable during preprocessing phase and types aligned in later phase since we create a list (which does implement `IEnumerable<T>`). Though this implementing behavior doesn't work when returning a single result of enumerable during async which wraps collection type inside Task.
The better fix is to assign `List<T>` as type since we are eventually creating a list.
In case of single result, the single result operator has generic type which will introduce convert node into it automatically which will match types for async tasks.

Resolves #27600
@ajcvickers ajcvickers added this to the 6.0.x milestone Mar 22, 2022
@mattfrear
Copy link

mattfrear commented May 12, 2022

Just chiming in to say that I also had this issue, and confirming that it is now fixed in the 6.0.5 release.

System.ArgumentException: Expression of type 'Task<List<MyType>>' cannot be used for return type 'Task<IEnumerable<MyType>>'

I didn't find this issue sooner because it doesn't mention ArgumentException and that is what I was searching google and GitHub for.

@AndriySvyryd AndriySvyryd modified the milestones: 6.0.x, 6.0.5 May 13, 2022
@AndriySvyryd AndriySvyryd added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label May 13, 2022
@AndriySvyryd AndriySvyryd changed the title Exceptions after upgrading from 6.0.1 to 6.0.3/6.0.2 Query exception after upgrading from 6.0.1 to 6.0.2 May 13, 2022
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 regression Servicing-approved type-bug
Projects
None yet
Development

No branches or pull requests

6 participants