Skip to content

Query builder with EF core can't return fsharp tuples (and sometimes new objects) using async methods #3782

@Lanayx

Description

@Lanayx

I'm getting an exсeption when using this code

    [<CLIMutable>]
    type Product =
        {
            Id: string
            Name: string
        }

    let db = new MyContext()
    let q = query {
        for p in db.Products do
        select (p.Id, p.Name)
    }
    let result = q.ToListAsync().Result

If I choose select p or select p.Id insead of select (p.Id, p.Name) , this works fine. If I write ToList instead of ToListAsync this works fine as well. C# version with Tuples works well. With provided F# code it fails with this exception:

Unhandled Exception: System.InvalidOperationException: The source IQueryable doesn't implement IAsyncEnumerable<System.Tuple`2[System.String,System
.String]>. Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations.
   at Microsoft.EntityFrameworkCore.Extensions.Internal.QueryableExtensions.AsAsyncEnumerable[TSource](IQueryable`1 source)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToke
n)

Also noticed that select { Id = p.Id; Name = p.Name } works, while select { Name = p.Name; Id = p.Id } doesn't and fails with exception:

Unhandled Exception: System.AggregateException: One or more errors occurred. (When called from 'VisitLambda', rewriting a node of type 'System.Linq
.Expressions.ParameterExpression' must return a non-null value of the same type. Alternatively, override 'VisitLambda' and change it to not visit c
hildren of this type.) ---> System.InvalidOperationException: When called from 'VisitLambda', rewriting a node of type 'System.Linq.Expressions.Par
ameterExpression' must return a non-null value of the same type. Alternatively, override 'VisitLambda' and change it to not visit children of this
type.
   at System.Linq.Expressions.ExpressionVisitor.VisitAndConvert[T](ReadOnlyCollection`1 nodes, String callerName)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.ExpressionVisitorBase.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalProjectionExpressionVisitor.Visit(Expression expression)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalProjectionExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallE
xpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalProjectionExpressionVisitor.Visit(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitSelectClause(SelectClause selectClause, QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitSelectClause(SelectClause selectClause, QueryModel queryModel)
   at Remotion.Linq.Clauses.SelectClause.Accept(IQueryModelVisitor visitor, QueryModel queryModel)
   at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateAsyncQueryExecutor[TResult](QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileAsyncQuery[TResult](QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileAsyncQueryCore[TResult](Expression query, INodeTypeProvider nodeTypeProvide
r, IDatabase database)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass24_0`1.<CompileAsyncQuery>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddAsyncQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileAsyncQuery[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.System.Collections.Generic.IAsyncEnumerable<TResult>.GetEnumerator()
   at System.Linq.AsyncEnumerable.<Aggregate_>d__6`3.MoveNext()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
  • Windows 10
  • .NET Core 2.0.0
  • Microsoft.EntityFrameworkCore 2.0
  • FSharp.Core 4.2.3
  • FSharp.NET.Sdk 1.0.5

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-QueriesQuery expressions and library implementationBugImpact-Medium(Internal MS Team use only) Describes an issue with moderate impact on existing code.

    Type

    Projects

    Status

    In Progress

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions