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

.Contains(.First) Query Throws InvalidOperationException in EF Core 8 #32691

Closed
pkariotis opened this issue Dec 30, 2023 · 5 comments
Closed

Comments

@pkariotis
Copy link

After upgrading from EF Core 6 to EF Core 8, I've noticed that a particular query construct now throws an InvalidOperationException due to the LINQ expression not be able to be translated.

Given the following entities: 

public class Foo
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long FooId { get; set; }

    public ICollection<Bar>? Bars { get; set; }
}

public class Bar
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long BarId { get; set; }

    [Required]
    public long FooId { get; set; }

    [ForeignKey(nameof(FooId))]
    public Foo? Foo { get; set; }

}

when I run the following query:

var bs = new List<long> { 1L, 2L, 3L };

await DbContext.Foos.Where(f => bs.Contains(f.Bars.First().BarId)).ToListAsync();

an InvalidOperationException is thrown with the following stacktrace:

System.InvalidOperationException
The LINQ expression 'DbSet<Foo>()
    .Where(f => __bs_0
        .Contains(MaterializeCollectionNavigation(
            Navigation: Foo.Bars,
            subquery: DbSet<Bar>()
                .Where(b => EF.Property<long?>(f, "FooId") != null && object.Equals(
                    objA: (object)EF.Property<long?>(f, "FooId"), 
                    objB: (object)EF.Property<long?>(b, "FooId"))))
            .First().BarId))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
   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.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   at UnitTests.SampleTests.FooBarTest() in C:\Repos\SampleTests\FooBarTests.cs:line 1095
   at Xunit.Sdk.TestInvoker`1.<>c__DisplayClass48_1.<<InvokeTestMethodAsync>b__1>d.MoveNext() in C:\Dev\xunit\xunit\src\xunit.execution\Sdk\Frameworks\Runners\TestInvoker.cs:line 264
--- End of stack trace from previous location ---
   at Xunit.Sdk.ExecutionTimer.AggregateAsync(Func`1 asyncAction) in C:\Dev\xunit\xunit\src\xunit.execution\Sdk\Frameworks\ExecutionTimer.cs:line 48
   at Xunit.Sdk.ExceptionAggregator.RunAsync(Func`1 code) in C:\Dev\xunit\xunit\src\xunit.core\Sdk\ExceptionAggregator.cs:line 90

The exception is thrown using both the In Memory and SQL Server LINQ providers and seems to be related to the use of the First operator in the Contains parameter. Can someone help me understand what's going on?

Thanks!

@roji
Copy link
Member

roji commented Dec 31, 2023

Duplicate of #32217

@roji roji marked this as a duplicate of #32217 Dec 31, 2023
@roji
Copy link
Member

roji commented Dec 31, 2023

Can you please try with the latest daily build and confirm the bug is gone? The fix will be released in an upcoming patch version.

@pkariotis
Copy link
Author

@roji Appears fixed in the latest daily build. Thanks!

@roji roji closed this as not planned Won't fix, can't repro, duplicate, stale Jan 2, 2024
@pkariotis
Copy link
Author

@roji Where can I look to find a release date for the fix? Thank you again.

@roji
Copy link
Member

roji commented Jan 2, 2024

The fix should come out in February. In the meantime you can continue using the daily build - it's generally very stable.

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

2 participants